首页 > 编程语言 >dubbo线程池又被打爆(打满)了java.util.concurrent.RejectedExecutionException: Thread pool is EXHAUSTED

dubbo线程池又被打爆(打满)了java.util.concurrent.RejectedExecutionException: Thread pool is EXHAUSTED

时间:2023-04-04 16:25:01浏览次数:43  
标签:dubbo java dump System blog 线程 日志 打爆 out

转载:https://blog.csdn.net/kevin_mails/article/details/121764780?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-121764780-blog-124236206.235%5Ev27%5Epc_relevant_recovery_v2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-121764780-blog-124236206.235%5Ev27%5Epc_relevant_recovery_v2&utm_relevant_index=2

最近线上系统经常告警dubbo线程池打满报错如下:

172.28.152.53/Caused by: java.util.concurrent.RejectedExecutionException: Thread pool is EXHAUSTED! Thread Name: DubboServerHandler-172.28.149.131:20880, Pool Size: 500 (active: 500, core: 500, max: 500, largest: 500), Task: 71795841 (completed: 71795342), Executor status:(isShutdown:false, isTerminated:false, isTerminating:false), in dubbo://172.28.149.131:20880!

对这个告警做了协查,记录一下,给大家一个参考。

dubbo线程池打满后,会立即生成一个线程dump文件,这里先去服用器上拿文件,立即生成一个线程dump文件需要配置一下启动参数

-Ddubbo.application.dump.directory=/data/dataLogs/jetty/dump
以后发生 dubbo线程池打满就到以到/data/dataLogs/jetty/dump下找文件,另外大家也可以通过jstack jmap等命令分析,我们因为投产使用不了,这里大家自行学习。

拿到dump文件后,打开看看

足足有2W多行,这么一行行看也没问题,这里推荐个分析工具:Smart Java thread dump analyzer - thread dump analysis in seconds

上传文件后,生产一个分析结果页面,很好用,如下图。

 

上图BLOCKED 的线程有2个,点进去看一下明细

 

综合业务和线程栈分析: 我们做了一个日志打印的aop,在方法入口切入,添加一个uuid生成的TraceID,通过MDC将日志串起来,我们使用java的UUID对象的randomUUID()生成id,randomUUID底层使用SecureRandom,像注释里讲了,多线程并发时,会BLOCK,所以性能不是很高。

 

解决办法:

我自己写一个方法:

package com.test.java8;

import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;

public class MyUUID {

// static final AtomicLong counter = new AtomicLong(System.nanoTime());
static final AtomicLong counter = new AtomicLong(System.currentTimeMillis());

public static String getUUID() {
return String.valueOf(counter.getAndIncrement());
}


public static String getUuid() {
return UUID.randomUUID().toString().replace("-", "");
}


public static void main(String[] args) {
int rCount = 100000000;
System.out.println("开始随机数生成测试!");
Long begin = System.currentTimeMillis();
for (int i = 0; i < rCount; i++) {
MyUUID.getUUID();
// System.out.println(MyUUID.getUUID());
}
System.out.printf("完成随机数生成,用时" + (System.currentTimeMillis() - begin) + "ms");

System.out.println("-----------------------------------------------------------------");

// Long begin2 = System.currentTimeMillis();
// for (int i = 0; i < rCount; i++) {
// MyUUID.getUuid();
// }
// System.out.printf("完成随机数生成,用时" + (System.currentTimeMillis() - begin2) + "ms");
// System.out.println(MyUUID.getUUID());
// System.out.println(MyUUID.getUuid());
}
}
注意!:不保证集群唯一的,这里因为主要是Trace 所以问题不大。如果有集群唯一的需求不要用我这个方法,可以参考SnowFlake等算法。

至此这个dump就分析完了。

那边在这次协查中,还有一个dump锁在了另外一个地方,贴一下图:

 

 

通过分析:

项目中使用的是logback的实现,项目配置的是AsyncAppender异步打印,异步打印日志会被存放在一个SynchronousQueue,然后再由消费线程来消费打印,以提升系统性能(建议大家生产一定要用异步),SynchronousQueue是阻塞队列,由于请求量大,打印的日志又多,最终导致消费速度跟不上,后面的添加队列都阻塞了,业务线程都夯在这里。

解决方案:

1.删除一些多余,无用日志(打印日志确实也很耗性能),打印尽量精简(我们通过此方法解决)。

2.升级日志框架(考虑中),目前log4j2看起来是不错的选择,官方也给了一些性能比较数据Log4j – Performance,log4j2的异步消息存储不是阻塞队列,是通过Disruptor高性能队列实现性能更强劲。更有美团在2016年将使用log4j2作为内部规范(高性能队列——Disruptor - 美团技术团队),哈哈,看来我们的步子还是有点慢了!

也做了一个集成log4j2的demo,仅供参考:GitHub - kevinmails/h2-test
————————————————
版权声明:本文为CSDN博主「kevin_mails」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/kevin_mails/article/details/121764780

 

标签:dubbo,java,dump,System,blog,线程,日志,打爆,out
From: https://www.cnblogs.com/ceshi2016/p/17286804.html

相关文章

  • wordpress粘贴图片自动上传到服务器(Java版)
    ​ 这种方法是servlet,编写好在web.xml里配置servlet-class和servlet-mapping即可使用后台(服务端)java服务代码:(上传至ROOT/lqxcPics文件夹下)<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><%@     page contentType="text/html;cha......
  • 记几次 [线上环境] Dubbo 线程池占满原因分析(第三次:GC STW)
    转载:https://blog.csdn.net/wsmalltiger/article/details/124236206前言  某天晚上正在开开心心写代码,忽然收到了线上告警:dubbo线程池活跃线程数告警、应用错误日志告警、dubbo线程池队列长度告警;瞬间意识到要出大事情了,得赶紧定位到原因并解决问题,不然时间长了肯定会影响商......
  • java使用浏览器请求下载pdf文件
    java使用浏览器请求下载pdf文件代码/***下载pdf文件**@parampdfFileUrl文件地址*@paramfileName文件名称*/publicstaticvoiddownloadPdf(StringpdfFileUrl,StringfileName){ServletRequestAttributesrequestAttributes=(ServletRequestAttr......
  • JavaScript:数组删除指定元素
    1.shift()方法用于删除数组中的第一个元素。注:此方法会改变数组的长度letarr=[1,2,3]arr.shift()//删除1//arr为[2,3]2.pop()方法用于删除数组中最后一个元素注:此方法会改变数组的长度letarr=[1,2,3]arr.pop();//删除3//arr为[1,2]3.splice()方法用于......
  • java抽象类和接口
    abstract由abstract关键字修饰的类称为抽象类,可以将某些类共有的行为抽象出来,形成约束,提高开发效率。//抽象类publicabstractclassAction{//抽象方法,只有方法名字,没有方法的实现publicabstractvoiddoSth();}抽象类不可以通过new关键字创建实例抽象类中可以有......
  • 使用JAVA实现布隆过滤器
    什么是布隆过滤器布隆过滤器是一种内存友好的数据结构,它可以高效地判断一个元素是否存在于一个集合中,以及大幅减少磁盘/数据库等IO操作。与哈希表和树等数据结构不同,它可以实现非常高的查找速度和存储效率,适用于需要快速并且高效地处理大数据集的场景。布隆过滤器原理布隆过滤......
  • java xxljob 根据参数运行业务
    配置定时任务不启动,手动执行根据传入的参数完成既定的业务 /** *自定义增删除平台酒体数据 *参数:startDate,endDate[yyyy-MM-dd) * *@return{@link*@return:com.xxl.job.core.biz.model.ReturnT<java.lang.String>} *@author:xxx *@date2023/3/12 **......
  • 深入理解 Java 中 SPI 机制
    vivo互联网技术微信公众号 作者:姜柱SPI(ServiceProviderInterface),是JDK内置的一种服务提供发现机制,本文由浅入深地介绍了JavaSPI机制。一、简介SPI(ServiceProviderInterface),是JDK内置的一种服务提供发现机制,可以用来启用框架扩展和替换组件,主要是被框架的开发人员使用,比如j......
  • 为什么 JavaScript 中 0.1 0.2 不等于 0.3 ?
    vivo互联网技术微信公众号 作者:刘洋在js中进行数学的运算时,会出现0.1+0.2=0.300000000000000004的结果,一开始认为是浮点数的二进制存储导致的精度问题,但这似乎不能很好的解释为什么在同样的存储方式下0.3+0.4=0.7可以得到正确的结果。本文主要通过浮点数的二进制存储及运算,和......
  • Kotlin 协程真的比 Java 线程更高效吗?
    vivo互联网技术微信公众号 作者:吴越网上几乎全部介绍Kotlin的文章都会说Kotlin的协程是多么的高效,比线程性能好很多,然而事情的真相真是如此么?协程的概念本身并不新鲜,使用C++加上内嵌汇编,一个基本的协程模型50行代码之内就可以完全搞出来。早在2013年国内就有团队开源了号称支持......