线程池对于接口 到底是灵丹妙药,还是潘多拉的魔盒

2020-05-13  本文已影响0人  Yellowtail

背景

我们公司有些接口之前比较慢,同事优化的时候,就使用线程池进行异步调用,然后 countdownlatch 等待执行完成
我之前只是觉得有问题,会影响并发,但是问题影响程度有多深,我就不知道了
这次有空研究了一下,分享在这里

有一个接口是这样的, 需要查询4次ES 得到4个数据,然后再组装一下进行返回

我们来尝试分析一下加了线程池之后,问题到底是啥

瞬时情况

我们来研究一个指标,就是:

一个闲置的系统,一瞬间涌入一些请求,随着并发量的上升, 系统响应速度是如何变化的

这个接口会调用4ES,得到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 下没有什么好的办法

上一篇 下一篇

猜你喜欢

热点阅读