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

# 线程池被打满的原因有哪些
当系统中接口的响应时间过长或者直接拒绝响应时,你此时里面就应该想到的是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,如果线程不能及时释放,总有被用完的一天。
线程池被打满的的情况,无非如下几种情况
- 业务逻辑执行的时间太长,比如sql执行太长,调用其他服务耗费的时间太长
- 系统流量突增
- 代码中有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)
当服务端的业务处理有问题,不能及时结束任务,就会造成越来越多的线程被阻塞,从而打满线程池,不能接受新的请求