dubbo 线程池

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

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值