线程池拒绝策略最佳实践

之前线上项目偶发出现线程池耗尽的问题,最近终于有空能好好研究一把,问题实际并不复杂,也得益于Dubbo线程池的拒绝策略才能很快找到大致的原因。

通过这个问题,也有些好奇各家使用的线程池拒绝策略是怎样的,刨刨坑、挖挖土,一起来看看吧~

问题背景

之前线上偶发出现线程池耗尽问题,现象如下:

在调用下游Dubbo接口时,提示Server端的线程池耗尽。

最开始以为是有突发流量,但是监控显示流量稳定,并且扩容后发现问题依然存在,渐渐意识到问题并不简单。

问题分析

既然有异常日志和堆栈,先看看到底什么场景下会出现这个异常。在Dubbo源码中,我们可以找到这一段提示出现在AbortPolicyWithReport中。

public class AbortPolicyWithReport extends ThreadPoolExecutor.AbortPolicy

AbortPolicyWithReport继承自 java.util.concurrent.ThreadPoolExecutor.AbortPolicy,是一种线程池拒绝策略,当线程池中的缓冲任务队列满,且线程数量达到最大时,就会触发拒绝策略,调用拒绝策略的rejectedExecution()方法进行处理。

那么,有哪些不同的拒绝策略呢?

JDK线程池拒绝策略

java.util.concurrent.ThreadPoolExecutor,我们可以找到JDK预设置的四种拒绝策略:

  • CallerRunsPolicy - 调用者线程处理

该策略下,如果线程池未关闭,则交由当前调用者线程进行处理,否则直接丢弃任务。

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    if (!e.isShutdown()) {
        r.run();
    }
}
  • AbortPolicy - 抛出异常

如果不配置拒绝策略的话,线程池会默认使用该策略,直接抛出rejectedExecution,交由上层业务处理。

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    throw new RejectedExecutionException("...");
}
  • DiscardPolicy - 丢弃当前任务

最简单的处理方法,直接丢弃。

//实际方法体就是空的,即该场景下不处理,直接丢弃
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}
  • DiscardOldestPolicy - 丢弃下一个要执行的任务

该策略是丢弃队列中最老的任务(其实就是下一个要执行的任务),并尝试执行当前任务。

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    if (!e.isShutdown()) {
        e.getQueue().poll();
        e.execute(r);
    }
}

Dubbo线程池拒绝策略

那么Dubbo的拒绝策略是怎样的呢?

其实从名字就能看出来,AbortPolicyWithReport

public class AbortPolicyWithReport extends ThreadPoolExecutor.AbortPolicy {
    ...
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        String msg = String.format("Thread pool is EXHAUSTED!" + ...);
        logger.warn(msg);
        dumpJStack();
        dispatchThreadPoolExhaustedEvent(msg);
        throw new RejectedExecutionException(msg)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值