Dubbo里面线程池的拒绝策略

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;
} @Override
public 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 minutes
//每 10 分钟,只打印一次。
if (now - lastPrintTime < 10 * 60 * 1000) {
return;
}
//获得信号量。保证,同一时间,有且仅有一个线程执行打印。
if (!guard.tryAcquire()) {
return;
}
//// 创建线程池,后台执行打印 JStack
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public 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 name
if(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));
// 打印 JStack
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();
}
}); } }
public class JVMUtil {
public static void jstack(OutputStream stream) throws Exception {
ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();
for (ThreadInfo threadInfo : threadMxBean.dumpAllThreads(true, true)) {
stream.write(getThreadDumpString(threadInfo).getBytes());
}
} private static String getThreadDumpString(ThreadInfo threadInfo) {
StringBuilder sb = new StringBuilder("\"" + threadInfo.getThreadName() + "\"" +
" Id=" + threadInfo.getThreadId() + " " +
threadInfo.getThreadState());
if (threadInfo.getLockName() != null) {
sb.append(" on " + threadInfo.getLockName());
}
if (threadInfo.getLockOwnerName() != null) {
sb.append(" owned by \"" + threadInfo.getLockOwnerName() +
"\" Id=" + threadInfo.getLockOwnerId());
}
if (threadInfo.isSuspended()) {
sb.append(" (suspended)");
}
if (threadInfo.isInNative()) {
sb.append(" (in native)");
}
sb.append('\n');
int i = 0; StackTraceElement[] stackTrace = threadInfo.getStackTrace();
MonitorInfo[] lockedMonitors = threadInfo.getLockedMonitors();
for (; i < stackTrace.length && i < 32; i++) {
StackTraceElement ste = stackTrace[i];
sb.append("\tat " + ste.toString());
sb.append('\n');
if (i == 0 && threadInfo.getLockInfo() != null) {
Thread.State ts = threadInfo.getThreadState();
switch (ts) {
case BLOCKED:
sb.append("\t- blocked on " + threadInfo.getLockInfo());
sb.append('\n');
break;
case WAITING:
sb.append("\t- waiting on " + threadInfo.getLockInfo());
sb.append('\n');
break;
case TIMED_WAITING:
sb.append("\t- waiting on " + threadInfo.getLockInfo());
sb.append('\n');
break;
default:
}
} for (MonitorInfo mi : lockedMonitors) {
if (mi.getLockedStackDepth() == i) {
sb.append("\t- locked " + mi);
sb.append('\n');
}
}
}
if (i < stackTrace.length) {
sb.append("\t...");
sb.append('\n');
} LockInfo[] locks = threadInfo.getLockedSynchronizers();
if (locks.length > 0) {
sb.append("\n\tNumber of locked synchronizers = " + locks.length);
sb.append('\n');
for (LockInfo li : locks) {
sb.append("\t- " + li);
sb.append('\n');
}
}
sb.append('\n');
return sb.toString();
}
}

最新文章

  1. Android Hook技术
  2. Xcode连接git@osc
  3. Feature Stapling in SharePoint 2010
  4. 一步一步实现基于Task的Promise库(一)Promise的基本实现
  5. 【转】HTTP响应报文与工作原理详解
  6. Bash中的数学计算
  7. 《java.util.concurrent 包源码阅读》13 线程池系列之ThreadPoolExecutor 第三部分
  8. vue+webpack+element-ui+git
  9. Spring Security之动态配置资源权限
  10. Java jvisualvm 远程监控tomcatt
  11. JS 操作样式 style
  12. [leetcode]46. Permutations全排列(给定序列无重复元素)
  13. js将一位数组分割成每三个一组
  14. Qt之获取子部件
  15. SQL Server提取字段中的所有数字
  16. Mysql索引机制B+Tree
  17. &amp;lt;二&amp;gt;读&amp;lt;&amp;lt;大话设计模式&amp;gt;&amp;gt;之策略模式
  18. position布局影响点击事件以及冒泡获取事件目标
  19. [android] post请求接口demo测试代码
  20. cogs 2039. 树的统计

热门文章

  1. WebGL概述
  2. Singleton and Prototype Bean Scope in Spring
  3. 高性能微服务网关.NETCore客户端Kong.Net开源发布
  4. vue computed监听多个属性
  5. 使用字蛛教程以及遇到的bug
  6. Visual Studio中Es6的开发环境搭建
  7. 开源FTP/SFTP客户端 FileZilla v3.31.0 绿色便携版
  8. 详细记录登录过程的用户、IP地址、shell命令以及详细操作时间
  9. Jenkins+Sonar搭建持续集成和代码质量检查环境
  10. Spring Bean 的装配方式