问题

前几天,我们的生产上突然出现了这样一个问题,调下面的查询方法报错,线程池满的问题,如下图:

问题思路

简单思考:我们都知道线程池的参数都包含什么含义!核心线程数,可建线程数,存储任务队列,拒绝策略!这块,大家不熟悉或者忘记的可以再补习补习!了解这几个参数我们不禁会问,任务处理不了,不是还有队列存储么?存储不了不是还有拒绝策略么?再者,怎么两百个线程就同时都被占用了?理论我们的场景没有这种量啊!带着这些问题,我们从源码中得到一些答案!

根据上面的问题,我找到了Dubbo相关源码,看一下生产版本2.6.5!我目前测试的版本是2.7.6,对比两个版本线程池这块的逻辑应该是差不多的,粘贴下源码:
类的位置:

源码如下:

public class AbortPolicyWithReport extends ThreadPoolExecutor.AbortPolicy {protected static final Logger logger = LoggerFactory.getLogger(AbortPolicyWithReport.class);private final String threadName;private final URL url;private static volatile long lastPrintTime = 0;private static Semaphore guard = new Semaphore(1);public AbortPolicyWithReport(String threadName, URL url) {this.threadName = threadName;this.url = url;}@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor e) {String msg = String.format("Thread pool is EXHAUSTED!" +" Thread Name: %s, Pool Size: %d (active: %d, core: %d, max: %d, largest: %d), Task: %d (completed: %d)," +" Executor status:(isShutdown:%s, isTerminated:%s, isTerminating:%s), in %s://%s:%d!",threadName, e.getPoolSize(), e.getActiveCount(), e.getCorePoolSize(), e.getMaximumPoolSize(), e.getLargestPoolSize(),e.getTaskCount(), e.getCompletedTaskCount(), e.isShutdown(), e.isTerminated(), e.isTerminating(),url.getProtocol(), url.getIp(), url.getPort());logger.warn(msg);dumpJStack();throw new RejectedExecutionException(msg);}private void dumpJStack() {long now = System.currentTimeMillis();//dump every 10 minutesif (now - lastPrintTime < 10 * 60 * 1000) {return;}if (!guard.tryAcquire()) {return;}Executors.newSingleThreadExecutor().execute(new Runnable() {@Overridepublic void run() {String dumpPath = url.getParameter(Constants.DUMP_DIRECTORY, System.getProperty("user.home"));SimpleDateFormat sdf;String OS = System.getProperty("os.name").toLowerCase();// window system don't support ":" in file nameif(OS.contains("win")){sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");}else {sdf = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss");}String dateStr = sdf.format(new Date());FileOutputStream jstackStream = null;try {jstackStream = new FileOutputStream(new File(dumpPath, "Dubbo_JStack.log" + "." + dateStr));JVMUtil.jstack(jstackStream);} catch (Throwable t) {logger.error("dump jstack error", t);} finally {guard.release();if (jstackStream != null) {try {jstackStream.flush();jstackStream.close();} catch (IOException e) {}}}lastPrintTime = System.currentTimeMillis();}});}}

根据上述源码,我们知道Dubbo定制了拒绝策略!从方法看,他是会把栈导出到系统文件的!Dubbo默认线程池核心线程数是200个的,可以通过参数设置!

复现问题

本地服务就可以制造个现场如下:
代码位置:码云链接
提供者代码:

@Service
public class TestApiImpl implements TestApi {private static Object lock = new Object();@Overridepublic void test(Test test) {System.out.println(Thread.currentThread().getName() + " 进入争抢资源...");synchronized (lock) {try {Thread.sleep(50000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("lock....." + Thread.currentThread().getName());}}
}

这里说一个小插曲:sleep是不会干预锁行为的!这点不同于wait方法!这个地方想要阻塞其他线程就要长期持有锁!

消费者代码:

@RestController
public class UserController {@Reference(timeout = 10000)private TestApi testApi;@GetMapping("/test")public void test(){Test test = new Test();testApi.test(test);}
}

启动服务之后,用jmeter测试一下:

开大于200个线程去调用/test的接口,就会报错:

有上面的源码可知,当出现这种情况的时候,会在系统用户的当前目录下生成出Dubbo_JStack.log.2020-05-22_11-55-23类似于这样的线程栈文件!我们可以通过这些信息查看都是为啥线程发生了阻塞等状况!

当然我们的例子我们是知道的,是因为对象锁被长期占用不释放导致的!

这里只是起到一个抛砖引玉的作用,提供大家思路去解决这样的问题!但是具体需要看一下,你们的问题到底是出在哪里?!是使用redis 无法初始化链接,连接数全部被占用!还是队列等问题,那就具体问题具体分析了,祝好!

Dubbo线程池问题思考Thread pool is EXHAUSTED!相关推荐

  1. 用了很多年Dubbo,连Dubbo线程池监控都不知道,觉得自己很厉害?

    前言 micrometer 中自带了很多其他框架的指标信息,可以很方便的通过 prometheus 进行采集和监控,常用的有 JVM 的信息,Http 请求的信息,Tomcat 线程的信息等. 对于一 ...

  2. 如何使用Arthas定位线上 Dubbo 线程池满异常

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | 公众号「Kirito的技术分享」 前言 本文是 ...

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

    作者 | 徐靖峰  阿里云高级开发工程师 前言 Dubbo 线程池满异常应该是大多数 Dubbo 用户都遇到过的一个问题,本文以 Arthas 3.1.7 版本为例,介绍如何针对该异常进行诊断,主要使 ...

  4. 记一次线上压测Dubbo线程池队列满的问题

    本文记录一次线上全链路压测出现的Dubbo线程池队列满的问题. 1 问题描述 线上做全链路压测,其中涉及三个系统,调用关系A->B->C,均是dubbo调用.压测的时候C出现CPU满导致服 ...

  5. [Done][DUBBO] dubbo Thread pool is EXHAUSTED!

    异常信息: com.alibaba.dubbo.remoting.ExecutionException: class com.alibaba.dubbo.remoting.transport.disp ...

  6. Dubbo线程池耗尽问题

    场景:dubbo 线程池耗尽,报错. Caused by: java.util.concurrent.RejectedExecutionException: Thread pool is EXHAUS ...

  7. Dubbo线程池满导致宕机的案例分析解决

    1 背景概述 线上事故:在做活动促销的时候,交易中台的商品服务发生了个别节点的宕机而此时间段内QPS并没有超过告警配置的线程数阈值1500. 于是决定做一次压测,当对自己的商品服务做压测20000个请 ...

  8. dubbo官方文档_不可忽视的Dubbo线程池

    问题描述 线上突然出现Dubbo超时调用,时间刚好为Consumer端设置的超时时间. 有好几个不同的接口都报超时了 第1次调用超时,第2次(或第3次)重试调用非常快(正常水平) Dubbo调用超时的 ...

  9. Dubbo 线上 Thread pool is EXHAUSTED 问题排查

    本文来自作者投稿,原创作者:Tom 前景提要 早上9点第一个到公司泡了一包枸杞,准备打开极客时间看两篇文章提提神.突然客服部反馈用户发送短信收取不到验证码还一通在有大领导的群里@所有人(负责这块的同事 ...

最新文章

  1. 线程安全(中)--彻底搞懂synchronized(从偏向锁到重量级锁)
  2. 扩增子分析解读3格式转换,去冗余,聚类
  3. 一个Portal处理流程
  4. 花椒web端实时互动流媒体播放器
  5. 【渝粤题库】广东开放大学 互联网营销 形成性考核
  6. 用计算机MR,计算机上的【MC、MR、M
  7. n元n次方程求解c 语言,解n元一次方程
  8. php链接mysql编码错误_php 操作 mysql 数据库 编码 错误
  9. 两个list取交集_利用jieba计算两个句子的相似度
  10. (转)替换回车符为换行符
  11. java迭代法求圆周率用梯形_感悟数学“近似计算”之美——“望星楼”里的圆周率...
  12. mybatis连接oracle
  13. Chrome历史版本以及ChromeDriver下载地址对应的版本
  14. 电话号码正则表达式(标准)
  15. 【机器人学】正运动学详解
  16. 又一位华为工程师倒下了 程序员的世界怎么了?
  17. 苹果税务信息填写教程
  18. 台大·林轩田·机器学习基石·第二讲
  19. 第三周总结(2022.10.31~2022.11.4)
  20. 如何批量压缩pdf文件到最小

热门文章

  1. swiper.js横向轮播插件
  2. 电脑之间快速传输超大文件(100GB以上)的方法
  3. 医疗行业容灾备份解决方案
  4. 微端服务器没有4个文件,微端服务器不传送数据库
  5. 零基础入门金融风控之贷款违约预测挑战赛-task01
  6. php去除编辑器html标签,js处理富文本编辑器转义、去除转义、去除HTML标签
  7. 【jupyter notebook 设置黑色背景,字体大小】
  8. 【5G】SRS原理 | SRS天线轮发
  9. 射频识别系统及WMS仓库管理系统功能介绍
  10. 全局修改样式(全局颜色更改)