Dubbo 线上 Thread pool is EXHAUSTED 问题排查

Posted Hollis

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dubbo 线上 Thread pool is EXHAUSTED 问题排查相关的知识,希望对你有一定的参考价值。


前景提要


早上9点第一个到公司泡了一包枸杞,准备打开极客时间看两篇文章提提神。突然客服部反馈用户发送短信收取不到验证码还一通在有大领导的群里@所有人(负责这块的同事还没来!!!)。


排查思路


第一时间查看消息中心日志,发现果不其然出现报错:


MessageService. Last error is: Failed to invoke remote method: threadpool is exhausted ,detail msg:Thread pool is EXHAUSTED! Thread Name: Pool Size:
200 (active: 200, core: 200, max: 200, largest: 200), Task: 16150 (completed: 15950)

RemotingException: Server side(192.168.10.65,18090) threadpool is exhausted ,detail msg:Thread pool is EXHAUSTED!

删减了一些敏感错误信息,不影响排查问题


看到Thread pool is EXHAUSTED几个关键字, 于是马上定位下游的短信服务肯定是爆了。 第一时间脑海中浮现的几个可能性是:


  • 情况一: 被人攻击,频繁盗刷, 导致接口请求超限

  • 情况二: 下游短信服务发送短信接口出现问题, 处理缓慢导致。最终导致请求超限

根据第一种情况, 简单的对当天请求验证码接口日志做了分析, 发现请求频率正常, 并不频繁,于是排除了第一种情况。


根据第二种情况查看并分析, 发现在半小时前消息中心请求短信服务接口超时,报错信息如下:


com.alibaba.dubbo.remoting.TimeoutException: Waiting server-side response timeout by scan timer. client elapsed: 0 ms, server elapsed: 20020 ms, timeout: 20000 ms


看到上面的超时异常信息更加坚定了第二种情况的判断。 最后查看下游短信服务发送短信接口日志,果不其然发现如下异常:


com.alibaba.druid.pool.DruidDataSource - create connection SQLException, url: jdbc:mysql:...., errorCode 9001, state HY000
java.sql.SQLException: Max connect timeout reached while reaching hostgroup 90 after 10985ms


What!获取数据库连接超时?喝了一口刚刚泡好的枸杞(此时温度刚刚好),想到几个可疑点:


  1. 短信服务中其他接口出现问题,执行缓慢并持有数据库连接没有进行释放。

  2. 短信服务的发送接口逻辑应该只是封装统一调用第三方短信平台, 可能由于第三方接口缓慢导致

终排查发现, 是由于短信发送接口请求第三方短信平台不稳定导致。

优化方案

review了短信接口代码, 里面只是做了简单的第三方短信平台api统一封装, 并不需要操作数据库更不需要事物(小伙伴为了方便还在类上面友好的加了@Transaction!) ,这时第三方短信平台请求缓慢时一直持有数据库连接。


针对第三方短信平台做故障处理机制。


欢迎各位补充。


如果你看完有收获,欢迎给作者赞赏。


有道无术,术可成;有术无道,止于术
欢迎大家关注 Java之道 公众号



好文章,我 在看❤️

以上是关于Dubbo 线上 Thread pool is EXHAUSTED 问题排查的主要内容,如果未能解决你的问题,请参考以下文章

Arthas | 定位线上 Dubbo 线程池满异常

Arthas | 定位线上 Dubbo 线程池满异常

后台打印:This application is modifying the autolayout engin from a background thread,which can lead to e

multiprocessing.Pool - PicklingError: Can't pickle <type 'thread.lock'>: 属性查找 thread.lock 失败

boost::asio::thread_pool - 如何在工作完成前取消工人?

使用 boost::asio::thread_pool 的 C++ 线程池,为啥我不能重用我的线程?