dubbo默认提供了三种线程池,分别是
fixed 固定大小线程池,启动时建立线程,不关闭,一直持有。
cached 缓存线程池,空闲一分钟自动删除,需要时重建。
limited 可伸缩线程池,但池中的线程数只会增长不会收缩。(为避免收缩时突然来了大流量引起的性能问题)。
fixed:
public class FixedThreadPool implements ThreadPool {
public Executor getExecutor(URL url) {
String name = url.getParameter(Constants.THREAD_NAME_KEY, Constants.DEFAULT_THREAD_NAME);//Dubbo
int threads = url.getParameter(Constants.THREADS_KEY, Constants.DEFAULT_THREADS);//200
int queues = url.getParameter(Constants.QUEUES_KEY, Constants.DEFAULT_QUEUES);//0
return new ThreadPoolExecutor(threads, threads, 0, TimeUnit.MILLISECONDS,
queues == 0 ? new SynchronousQueue() :
(queues < 0 ? new LinkedBlockingQueue()
: new LinkedBlockingQueue(queues)),
new NamedThreadFactory(name, true), new AbortPolicyWithReport(name, url));
}
}
cached:
public class CachedThreadPool implements ThreadPool {
public Executor getExecutor(URL url) {
String name = url.getParameter(Constants.THREAD_NAME_KEY, Constants.DEFAULT_THREAD_NAME);//Dubbo
int cores = url.getParameter(Constants.CORE_THREADS_KEY, Constants.DEFAULT_CORE_THREADS);//0
int threads = url.getParameter(Constants.THREADS_KEY, Integer.MAX_VALUE);//Integer.MAX_VALUE
int queues = url.getParameter(Constants.QUEUES_KEY, Constants.DEFAULT_QUEUES);//0
int alive = url.getParameter(Constants.ALIVE_KEY, Constants.DEFAULT_ALIVE);//60s
return new ThreadPoolExecutor(cores, threads, alive, TimeUnit.MILLISECONDS,
queues == 0 ? new SynchronousQueue() :
(queues < 0 ? new LinkedBlockingQueue()
: new LinkedBlockingQueue(queues)),
new NamedThreadFactory(name, true), new AbortPolicyWithReport(name, url));
}
}
limited:
public class LimitedThreadPool implements ThreadPool {
public Executor getExecutor(URL url) {
String name = url.getParameter(Constants.THREAD_NAME_KEY, Constants.DEFAULT_THREAD_NAME);//Dubbo
int cores = url.getParameter(Constants.CORE_THREADS_KEY, Constants.DEFAULT_CORE_THREADS);//0
int threads = url.getParameter(Constants.THREADS_KEY, Constants.DEFAULT_THREADS);//200
int queues = url.getParameter(Constants.QUEUES_KEY, Constants.DEFAULT_QUEUES);//0
return new ThreadPoolExecutor(cores, threads, Long.MAX_VALUE, TimeUnit.MILLISECONDS,
queues == 0 ? new SynchronousQueue() :
(queues < 0 ? new LinkedBlockingQueue()
: new LinkedBlockingQueue(queues)),
new NamedThreadFactory(name, true), new AbortPolicyWithReport(name, url));
}
}
provider端:默认是fixed
consumer端:默认是cached
默认线程大小是200
AbortPolicyWithReport:
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);
throw new RejectedExecutionException(msg);
}
可以通过如下更改:
在线程中的线程被耗尽时出现如下错误:
[img]http://dl2.iteye.com/upload/attachment/0119/9408/e43659cd-2f77-3ba8-8040-da2dfe83f53a.png[/img]
解决方式:
1.通过jstack -l pid进行分析,查看主要的锁资源争用情况,从而进行业务代码的排查
2.增大线程池的数量,默认是200
3.减小超时时间,避免业务处理时间过长,耗光所有的线程