背景
我们公司有些接口之前比较慢,同事优化的时候,就使用线程池进行异步调用,然后 countdownlatch
等待执行完成
我之前只是觉得有问题,会影响并发,但是问题影响程度有多深,我就不知道了
这次有空研究了一下,分享在这里
有一个接口是这样的, 需要查询4次ES
得到4个数据,然后再组装一下进行返回
我们来尝试分析一下加了线程池之后,问题到底是啥
瞬时情况
我们来研究一个指标,就是:
一个闲置的系统,一瞬间涌入一些请求,随着并发量的上升, 系统响应速度是如何变化的
这个接口会调用4
次ES
,得到4
个数字
假设每次调用需要耗时 30 ms
未经优化前,顺序调用,那么一个接口就是 120 ms
那么未经优化前 并发区间在 0-200
(tomcat 200个线程) 的时候,耗时固定为 120 ms
假设,这时候,开一个线程池,进行异步操作, 线程数量设置为 10
,我们来分析一下现象是什么样的
10个
线程,可以理解为10个管道, 第一批不用排队,耗时是 30ms

第一个请求,响应速度的确快了
然后把请求变多,就是下面这个样子

但是可能不直观,我现在把请求标上序号(都是同时进来的)再来看看

可以看到 同时进来多个请求, 只有幸运的10个请求能够在120ms前处理完成,其它的都需要排队
梳理了一下公式
假设 线程数量为 t
, 瞬时并发为 n
, 耗时为 x
公式为 $30+\lfloor\frac{n*4}{t}\rfloor30$

在线网站
我再画个图表

优化效果结论
并发小, [1-2]
线程池效果最明显,只有 30ms
并发变大, 到达 9
的时候,耗时已经一致了
并发继续变大, 耗时超过未优化方案,耗时趋势上升,且此时tomcat
线程池被阻塞, 请求无法及时处理
并发继续变大,所有线程都在等待, 崩溃
所以我们辛辛苦苦开了10
个线程,只能优化的并发数为 9
建议
这个问题
最优解决方案是 微服务
+ NIO
次一点的是 纯NIO
BIO
下没有什么好的办法
网友评论