duubo在互联网技术中是中的非常广泛的,从我实习到现在我所在的公司,都是使用的dubbo做rpc框架,所以这也导致了我们需要更加深入的去了解这门技术,因为我们的遇到的问题无时无刻都会存在,本次我就跟大家讲讲我的一次线上dubbo线程池耗尽的事故排查思路。
我写过dubbo系列的文章,大家看完这章后想了解更多dubbo细节可以查看往起文章:
Dubbo
- 高性能NIO框架-Netty
- Netty常见面试题总结
- 敖丙RPC的超时设置,一不小心搞了线上事故
- 敖丙找出Dubbo源码BUG,三歪夸了我一天
- Dubbo基础
- Dubbo的服务暴露过程
- Dubbo的服务引用过程
- Dubbo服务调用过程
- Dubbo的SPI机制是啥?
- Dubbo集群容错负载均衡
- Dubbo面试题
- RPC实践
- Netty
问题
在一天早上突然手机收到公司服务告警短信,线程池耗尽了?在去公司的路上首先回想的就是最近公司有活动?流量突增?大早上就有人在发布系统?还是某歪趁我不在又点坏了我的系统?
怀着种种思考在公司的群里看着同步信息,以上种种可能都被反驳!!!
以下就是当时的告警信息:
- RejectedExecutionException:Thread pool is EXHAUSTED (线程池耗尽了)! Thread Name: DubboServerHandler-xx.xx.xxx:2201, Pool Size: 300 (active: 283, core: 300, max: 300, largest: 300)
Q:这个问题怎么出现的呢?是不是我们扩大线程池就能解决问题呢?dubbo里面线程池默认实现是什么呢?
A:我们在排查问题的时候一定要有一种必须查出因果关系的思想才能对自己有一定的提升,凭借着这种思想我们一步一步向下揭开谜底。
带着问题,接下来我们去查看dubbo的代码配置,了解dubbo底层实现,只有了解底层实现我们才能更加准确的发现问题,处理问题,提升自己……
首先我们看下我们代码配置:
- <dubbo:protocol name="dubbo" port="${service.protocol.dubbo.port}" threads="${service.protocol.dubbo.threads}" register="${service.protocol.dubbo.register}" />
从抛出的异常上我们已经设置的线程池的大小为300了
- 这里我说明一个点,不是线程池配置的越大就越好,这个是授我们系统层面,以及配置JVM参数相关的。一般我们都是默认配置200 大致可以从这几方面去做考虑:
- 1.JVM参数:-Xms 初始堆大小 -Xmx 最大堆大小 -Xss 每个线程栈大小2.系统层面1.系统最大可创建的线程 2.公式线:程数量 = (机器本身可用内存 – (JVM分配的堆内存+JVM元数据区)) / Xss的值
言归正传我们开始看下撸点源码,这里我们以 2.7.19的版本为例