一、介绍

1 真实的使用过程中可能会因为使用fix模式的线程池,导致具体某些业务场景因为线程池中的线程数量 不足而产生错误,而很多业务研发是对这些无感知的,只有当出现错误的时候才会去查看告警或者通过 客户反馈出现严重的问题才去查看,结果发现是线程池满了。

2 所以可以在创建线程池的时,通过某些手 段对这个线程池进行监控,这样就可以进行及时的扩缩容机器或者告警。

二、 Dubbo已有线程池

1 fix: 表示创建固定大小的线程池。也是Dubbo默认的使用方式,默认创建的执行线程数为200,并 且是没有任何等待队列的。所以再极端的情况下可能会存在问题,比如某个操作大量执行时,可能 存在堵塞的情况。后面也会讲相关的处理办法。

2 cache: 创建非固定大小的线程池,当线程不足时,会自动创建新的线程。但是使用这种的时候需 要注意,如果突然有高TPS的请求过来,方法没有及时完成,则会造成大量的线程创建,对系统的 CPU和负载都是压力,执行越多反而会拖慢整个系统。

三、demo

1 新建module

image.png

2 引入依赖

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.apache.dubbo</groupId>
  4. <artifactId>dubbo</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.projectlombok</groupId>
  8. <artifactId>lombok</artifactId>
  9. <version>1.18.20</version>
  10. </dependency>
  11. </dependencies>

3 编写代码

image.png

  1. @Slf4j
  2. public class WatchingThreadPool extends FixedThreadPool implements Runnable {
  3. private static final double alarmPercent = 0.90;
  4. private final Map<URL, ThreadPoolExecutor> threadPoolMap = new ConcurrentHashMap<>();
  5. /**
  6. * 汇报自己状态
  7. */
  8. public WatchingThreadPool() {
  9. // 每隔三秒打印线程的执行情况 延时一秒 每隔三秒
  10. Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(this, 1, 3, TimeUnit.SECONDS);
  11. }
  12. @Override
  13. public Executor getExecutor(URL url) {
  14. final Executor executor = super.getExecutor(url);
  15. if (executor instanceof ThreadPoolExecutor) {
  16. threadPoolMap.put(url, (ThreadPoolExecutor) executor);
  17. }
  18. return executor;
  19. }
  20. @Override
  21. public void run() {
  22. // 遍历线程池
  23. threadPoolMap.forEach(((url, threadPoolExecutor) -> {
  24. // 计算相关的指标
  25. final int activeCount = threadPoolExecutor.getActiveCount();
  26. final int poolSize = threadPoolExecutor.getPoolSize();
  27. double usedPercent = activeCount / (poolSize * 1.0);
  28. log.info("activeCount:{}, poolSize:{}, userPercent:{}", activeCount, poolSize, usedPercent);
  29. if (usedPercent > alarmPercent) {
  30. log.error("线程池使用率超出阀值!!!host:{}, 当前使用率:{}, url:{}", url.getIp(), usedPercent * 100, url);
  31. }
  32. }));
  33. }
  34. }

4 配置类

image.png

5 provider 配置

1 配置
image.png
2 代码模拟 🏠睡眠时间看效果
image.png

6 消费者测试

image.png

image.png