背景
我们公司有些接口之前比较慢,同事优化的时候,就使用线程池进行异步调用,然后 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$
公式
在线网站
我再画个图表
image.png
优化效果结论
并发小, [1-2] 线程池效果最明显,只有 30ms
并发变大, 到达 9 的时候,耗时已经一致了
并发继续变大, 耗时超过未优化方案,耗时趋势上升,且此时tomcat线程池被阻塞, 请求无法及时处理
并发继续变大,所有线程都在等待, 崩溃
所以我们辛辛苦苦开了10个线程,只能优化的并发数为 9
建议
这个问题
最优解决方案是 微服务 + NIO
次一点的是 纯NIO
BIO 下没有什么好的办法













网友评论