netty的线程模型
在netty中存在两种线程,boss线程和worker线程。
1.boss线程
作用:
(1)accept客户端的连接
(2)将接收到连接注册到一个worker线程上。
个数:
通常情况下,服务端每绑定一个端口,开启一个boss线程。
2.worker线程
作用:
处理注册在其身上的连接connection上的各种io事件。
个数:
默认是:核数+1
注意:
(1)一个worker线程可以注册多个connection
(2)一个connection只能注册到一个worker线程上。
dubbo的事件派发策略和线程池
1.dubbo基于netty,有5种派发策略
(1)默认是all。所有消息都派发到线程斌,包括请求、响应、连接事件、断开事件、心跳等。即worker线程接收到事件后,将该事件提交到业务线程池,自己再去处理其他事情。
(2)direct:worker线程斌接收到事件后,由worker执行到底。
(3)message:只有请求响应消息派发到线程池,其它连接断开事件、心跳等消息,直接在IO线程上执行。
(4)execution:只请求消息派发到线程池,响应和其它连接断开事件、心跳等消息,直接在IO线程上执行。
(5)connection:在IO线程上,将连接断开事件放入队列,有序逐个执行,其它消息派发到线程池。
2. dubbo默认提供了三种业务线程池:
(1)fixed是固定大小的线程份,启动时建立线程,不关闭,地直持有。
(2)cached缓存线程池,空闲一分钟自动删除,需要时重建。
(3)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<Runnable>() :
(queues < 0 ? new LinkedBlockingQueue<Runnable>()
: new LinkedBlockingQueue<Runnable>(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<Runnable>() :
(queues < 0 ? new LinkedBlockingQueue<Runnable>()
: new LinkedBlockingQueue<Runnable>(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<Runnable>() :
(queues < 0 ? new LinkedBlockingQueue<Runnable>()
: new LinkedBlockingQueue<Runnable>(queues)),
new NamedThreadFactory(name, true), new AbortPolicyWithReport(name, url));
}
}
provider端:默认是fixed
consumer端:默认是cached
/org/apache/dubbo/remoting/transport/AbstractClient.java
protected ExecutorService createExecutor() {
return Executors.newCachedThreadPool(new NamedThreadFactory(CLIENT_THREAD_POOL_NAME + CLIENT_THREAD_POOL_ID.incrementAndGet() + "-" + getUrl().getAddress(), true));
}
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);
}
服务端
两种线程池:
1. io线程池:netty的boss和worker线程池
(1)boss:建立connection
(2)worker:处理注册在其身上的连接connection上各种io事件。
2. 业务线程池:fixedThreadPool(),与worker配合处理各种请求。
客户端
两种线程池:
1. io线程池:netty的boss和worker线程池。
(1)同上
2. 业务线程池:cachedThreadPool,与worker配合处理各种响应,最后得到响应后唤醒被阻塞的主线程。
最后欢迎大家访问我的个人网站:1024s