当前位置:首页 > 科技  > 软件

盘一盘这个没资格出现在面试环节的场景题

来源: 责编: 时间:2024-01-08 09:15:05 282观看
导读你好呀,我是歪歪。前两天在一个技术群里看到有人抛出一张图片,提出了这样的一个问题:请教一下,线程池可以做到根据任务的类型,来指定特定线程执行吗?图片了解了一下背景,是批量任务触发,从订单表中查询出“处理中”状态的订单

你好呀,我是歪歪。Ftd28资讯网——每日最新资讯28at.com

前两天在一个技术群里看到有人抛出一张图片,提出了这样的一个问题:Ftd28资讯网——每日最新资讯28at.com

请教一下,线程池可以做到根据任务的类型,来指定特定线程执行吗?Ftd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

了解了一下背景,是批量任务触发,从订单表中查询出“处理中”状态的订单,订单可能属于不同的通道,所以需要调用不同通道的接口。Ftd28资讯网——每日最新资讯28at.com

现在的方案是把订单查出来之后,往线程池里面扔,在异步任务里面判断当前订单是属于哪个通道,就调用哪个通道的查询接口:Ftd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

这是常规做法,看起来没有毛病。Ftd28资讯网——每日最新资讯28at.com

但是现在提问的这个哥们遇到了一个问题:有一个通道的查询接口特别慢,会占着线程池里面的线程资源,影响了其他两个通道的订单查询。Ftd28资讯网——每日最新资讯28at.com

举个极端的例子,比如你的线程池核心线程数就三个。Ftd28资讯网——每日最新资讯28at.com

假设一共有 5 笔数据,前 3 笔是通道 A 的,后面两笔分别是通道 B 和通道 C 的。Ftd28资讯网——每日最新资讯28at.com

结果现在通道 A 出问题了:Ftd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

直接把你的核心线程都占满了,剩下的两笔对应 B 和 C 通道的数据就在队列里面排着队,等着。Ftd28资讯网——每日最新资讯28at.com

你说这个合不合理?Ftd28资讯网——每日最新资讯28at.com

非常不合理,对不对?Ftd28资讯网——每日最新资讯28at.com

但是这个问题确实也是很常规,常规到它甚至没有资格作为一个场景面试题出现在面试环节中。Ftd28资讯网——每日最新资讯28at.com

问题在于不同的通道在共用同一个线程池,从而导致的相互影响。所以解决思路主要就是怎么把资源隔离开来。Ftd28资讯网——每日最新资讯28at.com

一般来说,大家能想到的第一个解决方案就是用 MQ 嘛:Ftd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

利用不同的队列,天然就把不同通道的订单给区分开了,在监听侧各自处理各自通道的数据,这样就达到了资源隔离的效果。Ftd28资讯网——每日最新资讯28at.com

这个方案应该是很常规了,但是这个常规方案立马就被毙了。Ftd28资讯网——每日最新资讯28at.com

因为:Ftd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

需要注意的是,他这里说的“系统内部”是指同一个微服务,也就是不允许一个微服务使用 MQ 来做“自产自销”。Ftd28资讯网——每日最新资讯28at.com

我个人认为是“自产自销”没有任何问题的,在这个场景下我完全可以借助它的特性帮我做数据分隔、异步处理数据,而且代码简单,逻辑清晰。Ftd28资讯网——每日最新资讯28at.com

但是既然是公司规定,可能有一些因地制宜的考虑,我们也不好去做过多的批判。Ftd28资讯网——每日最新资讯28at.com

反正就是 MQ 可以解决这个问题,但是老板并不采取这个方案。Ftd28资讯网——每日最新资讯28at.com

没关系,小脑壳一转,大多数同学就能立马就掏出了另外一个解决方案。Ftd28资讯网——每日最新资讯28at.com

你前面出问题的原因不是因为不同的通道在共用同一个线程池吗?Ftd28资讯网——每日最新资讯28at.com

那很简单,每个通道各自搞一个线程池。然后和 MQ 的方案类似,根据不同的通道扔到对应的线程池中去,自己玩自己的:Ftd28资讯网——每日最新资讯28at.com

这样即使某个通道出问题了,由于在线程池层面做了线程资源隔离,所以也不影响另外的通道进行数据处理。Ftd28资讯网——每日最新资讯28at.com

这个就是线程池隔离的方案。Ftd28资讯网——每日最新资讯28at.com

其实关于这个方案,我当时还想到了另外一种原理一致,实现形式不一样,但是最终被认为是比较 low 的一个回答。Ftd28资讯网——每日最新资讯28at.com

因为他抛出的这个图片,我第一眼理解错了,我以为是按照通道分组,然后用单线程一个个的去调用查询接口,避免并发调用:Ftd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

所以我提到了一个叫做 KeyAffinityExecutor 的魔改线程池:Ftd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

这个线程池,它有一个比较厉害的特性,可以确保投递进来的任务按某个维度划分出任务,然后按照任务提交的顺序依次执行。这个线程池可以通过并行处理(多个线程)来提高吞吐量、又能保证一定范围内的任务按照严格的先后顺序来运行。Ftd28资讯网——每日最新资讯28at.com

对比到当前的这个问题中。Ftd28资讯网——每日最新资讯28at.com

可以按照通道维度进行任务划分,然后把任务往线程池扔的时候,就会被分配到不同的线程中去。Ftd28资讯网——每日最新资讯28at.com

关于这个线程池,我之前写了这篇文章,有兴趣的可以去了解一下,不赘述了:《看到一个魔改线程池,面试素材加一!》Ftd28资讯网——每日最新资讯28at.com

本质上还是线程池隔离的思路,只不过一个是分多个不同的业务线程池,线程池和业务绑定。一个是一个大线程池里面包了多个线程池,线程池可以通过分配规则的方式指定。Ftd28资讯网——每日最新资讯28at.com

同一个思路的不同实现方案而已。Ftd28资讯网——每日最新资讯28at.com

但是为什么我说我提出的这个魔改线程池的方案 low 呢?Ftd28资讯网——每日最新资讯28at.com

因为人家只是需要分组的特性,而不需要“按照任务提交的顺序依次执行”的特性。Ftd28资讯网——每日最新资讯28at.com

反而会出现如果一个通道的订单多,只有一个线程来处理,导致性能不够,任务堆积的情况。Ftd28资讯网——每日最新资讯28at.com

但是,话说回来,你也可以魔改一下这个魔改线程池,把里面的小线程池的核心线程数搞多点,就行了。Ftd28资讯网——每日最新资讯28at.com

总之,都是线程池隔离的思路。Ftd28资讯网——每日最新资讯28at.com

好了,这个方案我又讲完了,谁赞成,谁反对?Ftd28资讯网——每日最新资讯28at.com

看着没有任何问题,但是实际情况是:Ftd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

卧槽,50 多个?Ftd28资讯网——每日最新资讯28at.com

这特么的,简历还给我,我不面了,告辞。Ftd28资讯网——每日最新资讯28at.com

确实,如果是只有三个通道,或者多说点,五个通道嘛,我觉得用上面这个方案做线程池维度的隔离,都是可以接受的。Ftd28资讯网——每日最新资讯28at.com

但实际情况是 50 多个通道,一想起项目里面有 50 多个线程池在跑,这个就有点难受了。Ftd28资讯网——每日最新资讯28at.com

好了,现在 MQ 和线程池隔离的方案都被否决了,接下来的思路是什么?Ftd28资讯网——每日最新资讯28at.com

没有思路没有关系,我们再来读读题:批量任务触发,从订单表中查询出“处理中”状态的订单,订单可能属于不同的通道,所以需要调用不同通道的接口。但是某个通道慢,导致影响了其他通道订单的查询。Ftd28资讯网——每日最新资讯28at.com

问怎么办?Ftd28资讯网——每日最新资讯28at.com

某个通道慢,该怎么办?Ftd28资讯网——每日最新资讯28at.com

有的通道慢,有的通道快,我该怎么办?Ftd28资讯网——每日最新资讯28at.com

等等...Ftd28资讯网——每日最新资讯28at.com

前面我们按照通道维度分线程池被否了的原因是通道太多了。Ftd28资讯网——每日最新资讯28at.com

但是其实针对响应快的通道,我们完全不需要做线程池隔离,他们完全可以使用同一个线程池嘛,反正都是唰唰唰的就查回来了。Ftd28资讯网——每日最新资讯28at.com

所以,我们只需要搞两个线程池,一个处理通道响应快的,比如把接口调用的超时时间设置为 1s。另外一个处理通道响应慢的,超时时间直接拉满到 30s,自己慢慢玩去:Ftd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

至于怎么去判断通道到底是快是慢呢?Ftd28资讯网——每日最新资讯28at.com

这里又可以大致分为三个不同的方案了。Ftd28资讯网——每日最新资讯28at.com

第一个方案就是已知某几个通道是慢的,那就代码里面写硬编码都行。虽然不优雅,但是这确实也是一个在实际生产中常常被提及的一个快速解决问题的方案。Ftd28资讯网——每日最新资讯28at.com

第二个方案就是配置化,可以做个配置表,来配置通道的快慢标识。程序里面根据当前订单的通道,来表里面获取当前通道的快慢标识,从而把订单扔到不同的线程池中去。Ftd28资讯网——每日最新资讯28at.com

在这个方案中,用配置表代替了硬编码,但是还是需要人工基于线下沟通或者数据监控的方式去调整通道的快慢标识。Ftd28资讯网——每日最新资讯28at.com

你知道的,线上程序这玩意,一旦涉及到人工介入,就遭老罪了,很不爽。Ftd28资讯网——每日最新资讯28at.com

所以这个方案,有一点优雅,但是不多。Ftd28资讯网——每日最新资讯28at.com

第三个方案就是配置化加自动化这一套组合拳。Ftd28资讯网——每日最新资讯28at.com

配置化还是指前面提到的配置表。Ftd28资讯网——每日最新资讯28at.com

但是这个表中通道的快慢标识,就不需要人工来介入了,完全由程序自己收集信息,进行判断。Ftd28资讯网——每日最新资讯28at.com

比如,我们可以假设一开始的时候所有的通道都能快速响应。但是突然某个通道开始“扯拐”,响应时长出现波动,1s 内没有响应成功,那么这个任务就会超时,就可以把这个任务扔到慢通道线程池中去处理,同时对该通道的失败次数进行记录。Ftd28资讯网——每日最新资讯28at.com

当某个时间段失败次数超过某个阈值之后,则在配置表中标识该通道为慢通道。Ftd28资讯网——每日最新资讯28at.com

这样当下一个属于该通道的订单过来时,就会直接被扔到慢通道线程池中去。Ftd28资讯网——每日最新资讯28at.com

这样,就由程序完成了通道由“快标识”到“慢标识”的处理。Ftd28资讯网——每日最新资讯28at.com

那么当这个通道的问题解决之后,它又变成一个快通道时,怎么去修改它在配置表中的标识呢?Ftd28资讯网——每日最新资讯28at.com

很简单,同样的逻辑,在慢通道线程池处理的过程中,记录某个时间段某个通道的平均响应时长,如果低于指定阈值,比如 1s,则在配置表中重新标识该通道为快通道。Ftd28资讯网——每日最新资讯28at.com

整个过程,不管标识怎么变化,都是基于程序自动的数据统计来的,完全不需要人工介入。Ftd28资讯网——每日最新资讯28at.com

甚至你还可以加一个逻辑:当配置表中的通道都是快通道时,两个线程池都可以用起来,实现资源利用的最大化。Ftd28资讯网——每日最新资讯28at.com

优雅,非常优雅。Ftd28资讯网——每日最新资讯28at.com

至于怎么去统计线程池中的任务“某个时间段失败次数”和“某个时间段某个通道的平均响应时长”这样的统计信息,在线程池里面,专门留了这两个方法给你去在任务执行之前和之后搞事情,完全可以基于这两个方法做一些统计工作:Ftd28资讯网——每日最新资讯28at.com

java.util.concurrent.ThreadPoolExecutor#runWorkerFtd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

就目前提出的方案来说,把通道分为快慢通道,然后划分为线程池是最满足提问者的需求的。Ftd28资讯网——每日最新资讯28at.com

最后应该就拿着这个方案去汇报了。Ftd28资讯网——每日最新资讯28at.com

汇报题目我都帮忙想好了:Ftd28资讯网——每日最新资讯28at.com

《基于通道关键指标收集分析的全自适应、高敏感度、资源利用最大化的调度方案汇报》Ftd28资讯网——每日最新资讯28at.com

剩下的,就看你怎么去吹了。Ftd28资讯网——每日最新资讯28at.com

除去前面的方案外,其实我还想到一个“比较奇葩”的解决方案。Ftd28资讯网——每日最新资讯28at.com

因为他的业务场景是定时任务嘛,所以我想起了之前写过的这篇文章:《又被夺命连环问了!从一道关于定时任务的面试题说起。》Ftd28资讯网——每日最新资讯28at.com

既然能区分出来通道的快慢,那么在定时任务启动之后,我们就可以把“快慢标识”传递到服务器中去,服务器就能把订单分为快慢两大类,然后一台机器处理通道慢的订单数据,一台处理快的:Ftd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

这样我就能从服务器这个物理层面就把数据区分开了。Ftd28资讯网——每日最新资讯28at.com

所以只要能标识开区分数据,那么理论上不仅可以在代码中区分,也可以往上抽离一层,通过服务器维度区分。Ftd28资讯网——每日最新资讯28at.com

但是好处是什么呢?Ftd28资讯网——每日最新资讯28at.com

呃...Ftd28资讯网——每日最新资讯28at.com

看起来确实没什么好处,只是这个方案比较奇葩,一般没人想到,我就是顺便提一嘴,主要是显摆一下。Ftd28资讯网——每日最新资讯28at.com

不显摆一下,装装逼,总感觉不得劲。Ftd28资讯网——每日最新资讯28at.com

类似的场景

基于提问者的这个问题,歪师傅也想起了两个类似的场景。Ftd28资讯网——每日最新资讯28at.com

一个是我参与开发过的一个对客发送短信的消息系统,简化一下整个流程大概是这样的:Ftd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

上面这个图片会出现什么问题呢?Ftd28资讯网——每日最新资讯28at.com

就是消息堆积。Ftd28资讯网——每日最新资讯28at.com

当某个业务系统调用短信发送接口,批量发送消息的时候,比如发送营销活动时,大量的消息就在队列里面堆着,慢慢消费。Ftd28资讯网——每日最新资讯28at.com

其实堆积也没有关系,毕竟营销活动的实时性要求不是那么高,不要求立马发送到客户手机上去。Ftd28资讯网——每日最新资讯28at.com

但是,如果在消息堆积起来之后,突然有用户申请了验证码短信呢?Ftd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

需要把前面堆积的消费完成后,才会发送验证码短信,这个已经来不及了,甚至验证码已经过期很久了你才发过去。Ftd28资讯网——每日最新资讯28at.com

客户肯定会骂娘,因为获取不到验证码,他就不能进行后续业务。Ftd28资讯网——每日最新资讯28at.com

如果大量客户因为收不到验证码不能进行后续业务,引起群体性的客诉,甚至用户恐慌,这个对于企业来说是一个非常严重的事件。Ftd28资讯网——每日最新资讯28at.com

怎么办呢?Ftd28资讯网——每日最新资讯28at.com

解决方案非常简单,再搞一个“高速”队列出来:Ftd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

验证码消息直接扔到“高速”队列中去,这个队列专门用来处理验证码、动账通知这一类时效性要求极高的消息,从业务场景上分析,也不会出现消息堆积。Ftd28资讯网——每日最新资讯28at.com

不是特别复杂的方案,大道至简,问题得到了解决。Ftd28资讯网——每日最新资讯28at.com

类比到前面说的“快慢”线程池,其实是一样的思想,都是从资源上进行隔离。Ftd28资讯网——每日最新资讯28at.com

只不过我说的这个场景更加简单,不需要去收集信息进行动态判断。业务流程上天然的就能区分出来,哪些消息实时性比较高,应该走“高速”队列;哪些消息慢慢 发没关系,可以应该走“常规”队列。Ftd28资讯网——每日最新资讯28at.com

而这个所谓的“高速”和“常规”,只是开发人员给一个普通队列赋予的一个属性而已,站在 MQ 的角度,这两个队列没有任何区别。Ftd28资讯网——每日最新资讯28at.com

另外一个场景是我想起了之前写过的这篇文章:《我试图给你分享一种自适应的负载均衡。》Ftd28资讯网——每日最新资讯28at.com

我们还是先看看前面出现的这个图:Ftd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

图中的线程池,不管是快的还是慢的,本质上他们处理的请求都是一样的,即拿着订单去对应的通道查询订单结果。Ftd28资讯网——每日最新资讯28at.com

那我们是不是可以把这两个线程池抽象一下,理解为部署了同一个服务的两个不同的服务器,一个服务器的性能好,一个服务器的性能差。Ftd28资讯网——每日最新资讯28at.com

现在有一个请求过来了,理论上这两个服务器都能处理这个请求,所以我们通过某个逻辑选一个服务器出来,把请求发过去。Ftd28资讯网——每日最新资讯28at.com

这个“某个逻辑”不就是我们常说的负载均衡算法吗?Ftd28资讯网——每日最新资讯28at.com

负载均衡算法的算法有很多:Ftd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

其中这几个都是需要统计服务端的相关数据,基于数据进行分析,最终觉得把当前请求发个哪个服务器:Ftd28资讯网——每日最新资讯28at.com

图片图片Ftd28资讯网——每日最新资讯28at.com

这个逻辑,和我们前面提到的这句话,其实是一脉相承的,都是信息收集、指标分析、阈值设定:Ftd28资讯网——每日最新资讯28at.com

去统计线程池中的任务“某个时间段失败次数”和“某个时间段某个通道的平均响应时长”这样的统计信息Ftd28资讯网——每日最新资讯28at.com

你想想我们最开始的问题是“一个通道慢了,影响了其他通道的数据,怎么办?”Ftd28资讯网——每日最新资讯28at.com

现在我带着你扯到了“负载均衡策略”。Ftd28资讯网——每日最新资讯28at.com

这两个场景不能说八竿子打不着吧,但是它们确实在一定程度上有相似性,转好几个弯之后,也能联系到一起。Ftd28资讯网——每日最新资讯28at.com

你要是再发散一点,你甚至能想到 Serverless 的弹性场景,通过收集 CPU、Mem 指标、QPS、RT、TCP 连接数等指标,进行综合判断,弹性扩容,也无需人工介入,手动扩容。Ftd28资讯网——每日最新资讯28at.com

所以,朋友,这个事情告诉我们一个什么道理?Ftd28资讯网——每日最新资讯28at.com

向上抽象问题的能力,把看看似不一样的场景抽离成类似的问题模型的能力很重要。Ftd28资讯网——每日最新资讯28at.com

还有,“一个通道慢需要进行资源隔离”这个问题的关键不在于“一个通道”上,虽然可以在通道层面做隔离,但是这样并没有抓住问题的关键。问题的关键在于“通道慢”,所以可以在“快慢”的维度上做隔离,这才是问题的关键。Ftd28资讯网——每日最新资讯28at.com

关键问题,就是要找到问题的关键。Ftd28资讯网——每日最新资讯28at.com

这也是我在这一次群聊的讨论中学习到的东西。Ftd28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-57868-0.html盘一盘这个没资格出现在面试环节的场景题

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 如果把AOP、过滤器和拦截器一起放在Spring Boot中,会发生什么呢?

下一篇: 图形编辑器开发:自定义光标

标签:
  • 热门焦点
  • 官方承诺:K60至尊版将会首批升级MIUI 15

    全新的MIUI 15今天也有了消息,在官宣了K60至尊版将会搭载天玑9200+处理器和独显芯片X7的同时,Redmi给出了官方承诺,K60至尊重大更新首批升级,会首批推送MIUI 15。也就是说虽然
  • 2023年Q2用户偏好榜:12+256G版本成新主流

    3月份的性能榜、性价比榜和好评榜之后,就要轮到2023年的第二季度偏好榜了,上半年的新机潮已经过去,最明显的肯定就是大内存和存储的机型了,另外部分中端机也取消了屏幕塑料支架
  • 线程通讯的三种方法!通俗易懂

    线程通信是指多个线程之间通过某种机制进行协调和交互,例如,线程等待和通知机制就是线程通讯的主要手段之一。 在 Java 中,线程等待和通知的实现手段有以下几种方式:Object 类下
  • 企业采用CRM系统的11个好处

    客户关系管理(CRM)软件可以为企业提供很多的好处,从客户保留到提高生产力。  CRM软件用于企业收集客户互动,以改善客户体验和满意度。  CRM软件市场规模如今超过580
  • 猿辅导与新东方的两种“归途”

    作者|卓心月 出品|零态LT(ID:LingTai_LT)如何成为一家伟大企业?答案一定是对“势”的把握,这其中最关键的当属对企业战略的制定,且能够站在未来看现在,即使这其中的
  • 三星Galaxy Z Fold5今日亮相:厚度缩减但仍略显厚重

    据官方此前宣布,三星将于7月26日也就是今天在韩国首尔举办Unpacked活动,届时将带来带来包括Galaxy Buds 3、Galaxy Watch 6、Galaxy Tab S9、Galaxy
  • iQOO Neo8系列今日官宣:首发天玑9200+ 全球安卓最强芯!

    在昨日举行的的联发科新一代旗舰芯片天玑9200+的发布会上,iQOO官方也正式宣布,全新的iQOO Neo8系列新品将全球首发搭载这款当前性能最强大的移动平台
  • Android 14发布:首批适配机型公布

    5月11日消息,谷歌在今天凌晨举行了I/O大会,本次发布会谷歌带来了自家的AI语言模型PaLM 2、谷歌Pixel Fold折叠屏、谷歌Pixel 7a手机,同时发布了Androi
  • OPPO K11评测:旗舰级IMX890加持 2000元档最强影像手机

    【Techweb评测】中端机型用户群体巨大,占了中国目前手机市场的大头,一直以来都是各手机品牌的“必争之地”,其中OPPO K系列机型一直以来都以高品质、
Top