一、介绍
1 真实的使用过程中可能会因为使用fix模式的线程池,导致具体某些业务场景因为线程池中的线程数量 不足而产生错误,而很多业务研发是对这些无感知的,只有当出现错误的时候才会去查看告警或者通过 客户反馈出现严重的问题才去查看,结果发现是线程池满了。
2 所以可以在创建线程池的时,通过某些手 段对这个线程池进行监控,这样就可以进行及时的扩缩容机器或者告警。
二、 Dubbo已有线程池
1 fix: 表示创建固定大小的线程池。也是Dubbo默认的使用方式,默认创建的执行线程数为200,并 且是没有任何等待队列的。所以再极端的情况下可能会存在问题,比如某个操作大量执行时,可能 存在堵塞的情况。后面也会讲相关的处理办法。
2 cache: 创建非固定大小的线程池,当线程不足时,会自动创建新的线程。但是使用这种的时候需 要注意,如果突然有高TPS的请求过来,方法没有及时完成,则会造成大量的线程创建,对系统的 CPU和负载都是压力,执行越多反而会拖慢整个系统。
三、demo
1 新建module
2 引入依赖
<dependencies><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version></dependency></dependencies>
3 编写代码

@Slf4jpublic class WatchingThreadPool extends FixedThreadPool implements Runnable {private static final double alarmPercent = 0.90;private final Map<URL, ThreadPoolExecutor> threadPoolMap = new ConcurrentHashMap<>();/*** 汇报自己状态*/public WatchingThreadPool() {// 每隔三秒打印线程的执行情况 延时一秒 每隔三秒Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(this, 1, 3, TimeUnit.SECONDS);}@Overridepublic Executor getExecutor(URL url) {final Executor executor = super.getExecutor(url);if (executor instanceof ThreadPoolExecutor) {threadPoolMap.put(url, (ThreadPoolExecutor) executor);}return executor;}@Overridepublic void run() {// 遍历线程池threadPoolMap.forEach(((url, threadPoolExecutor) -> {// 计算相关的指标final int activeCount = threadPoolExecutor.getActiveCount();final int poolSize = threadPoolExecutor.getPoolSize();double usedPercent = activeCount / (poolSize * 1.0);log.info("activeCount:{}, poolSize:{}, userPercent:{}", activeCount, poolSize, usedPercent);if (usedPercent > alarmPercent) {log.error("线程池使用率超出阀值!!!host:{}, 当前使用率:{}, url:{}", url.getIp(), usedPercent * 100, url);}}));}}
4 配置类
5 provider 配置
6 消费者测试



