# 生产问题:线程池被打满

在这里插入图片描述

# 线程池被打满的原因有哪些

当系统中接口的响应时间过长或者直接拒绝响应时,你此时里面就应该想到的是Dubbo线程池是否被打满了?然后去监控系统看一下线程池的活跃连接数。

Dubbo线程池被打满应该是一个很常见的问题,那么线程池为什么会被打满呢?

public class FixedThreadPool implements ThreadPool {

    @Override
    public Executor getExecutor(URL url) {
        String name = url.getParameter(THREAD_NAME_KEY, DEFAULT_THREAD_NAME);
        int threads = url.getParameter(THREADS_KEY, DEFAULT_THREADS);
        int queues = url.getParameter(QUEUES_KEY, DEFAULT_QUEUES);
        return new ThreadPoolExecutor(threads, threads, 0, TimeUnit.MILLISECONDS,
                queues == 0 ? new SynchronousQueue<Runnable>() :
                        (queues < 0 ? new LinkedBlockingQueue<Runnable>()
                                : new LinkedBlockingQueue<Runnable>(queues)),
                new NamedInternalThreadFactory(name, true), new AbortPolicyWithReport(name, url));
    }

}

因为默认情况下Dubbo线程池的类型是固定长度线程池,线程池中的数量为200,如果线程不能及时释放,总有被用完的一天。

线程池被打满的的情况,无非如下几种情况

  1. 业务逻辑执行的时间太长,比如sql执行太长,调用其他服务耗费的时间太长
  2. 系统流量突增
  3. 代码中有bug,如发生死循环,死锁等

# 复现Dubbo线程池被打满

服务端配置最大线程数为3 application.yaml

dubbo:
  protocol:
    threads: 3

每接受一个请求,就等待1分钟,模拟请求缓慢的情景

@Service
public class EchoServiceImpl implements EchoService {

    @Override
    public String hello(String msg) {
        try {
            TimeUnit.MINUTES.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return msg;
    }
}

服务端多次调用后抛出如下异常,表明服务端线程池已经被打满

org.apache.dubbo.remoting.RemotingException: Server side(192.168.97.137,20881) threadpool is exhausted ,detail msg:Thread pool is EXHAUSTED! Thread Name: DubboServerHandler-192.168.97.137:20881, Pool Size: 3 (active: 3, core: 3, max: 3, largest: 3), Task: 9 (completed: 6), Executor status:(isShutdown:false, isTerminated:false, isTerminating:false), in dubbo://192.168.97.137:20881!
	at org.apache.dubbo.remoting.exchange.support.DefaultFuture.doReceived(DefaultFuture.java:191)
	at org.apache.dubbo.remoting.exchange.support.DefaultFuture.received(DefaultFuture.java:153)
	at org.apache.dubbo.remoting.exchange.support.DefaultFuture.received(DefaultFuture.java:141)

当服务端的业务处理有问题,不能及时结束任务,就会造成越来越多的线程被阻塞,从而打满线程池,不能接受新的请求