dubbo的线程模型、派发策略、线程池策略

Dubbo的线程模型由Netty的IO线程和自定义线程池组成,派发策略包括AllDispatcher、DirectDispatcher、ConnectionOrderedChannelHandler、ExecutionChannelHandler和MessageOnlyChannelHandler。不同策略决定请求是交给线程池处理还是IO线程处理。例如,DirectDispatcher将所有请求交给IO线程,而ExecutionChannelHandler仅派发请求到线程池。线程池策略包括cache、limit、fix和eager,分别对应不同场景的使用需求。
摘要由CSDN通过智能技术生成

dubbo提供了自己的线程池以及派发策略,其实官方文档上讲的是比较清楚的,只需要结合着源码看下,就能明白具体的原理
dubbo官方文档地址

线程模型

在这里插入图片描述

用简单的总结来说,dubbo中的线程模型是有netty本身的io线程 + dubbo提供的线程池组成的,也就是说,不管是正常的请求、还是响应、还是连接请求、断开连接请求,要么是有netty的io线程来执行,要么是线程池中的线程来执行
不同的派发策略,会有不同的处理效果

派发策略以及源码

根据官网的解释,有以下五种派发策略,在自己去学习这五个策略的时候,我一直不明白是如何实现有些请求可以交给线程池去处理,有些请求会交给io线程去处理,看了源码之后,就理解了
在这里插入图片描述
问题:
1、首先有五个派发策略,其中有四个都继承了WrappedChannelHandler, 为什么单单direct没有继承?
2、是如何实现请求是要到线程池中?还是到io线程中执行呢?
先回答第二个问题,wrappedChannelHandler是一个handler,是会被netty执行的,所以,如果我们没有做其他处理,默认执行wrappedChannelHandler中的方法,那其实就是把请求交给了netty的io线程去执行
在dubbo中,五个dispatcher类,通过覆写wrappedChannelHandler的方法,来决定是要交给线程池执行?还是io线程执行
也就是说,如果连接事件,要交给线程池执行,那就覆写connect()方法,在子类的connect方法中,将请求交给线程池即可
如果断开连接事件,要交给io线程执行,就不需要在子类中覆写disConnect()方法

WrappedChannelHandler#getExecutorService()

这里先插一段代码,因为这段代码是前提,就是根据dubbo的自适应扩展机制以及我们的配置,来获取一个线程池,默认是fix

public WrappedChannelHandler(ChannelHandler handler, URL url) {
   
    this.handler = handler;
    this.url = url;
    //初始化线程池,根据adaptive机制,获取dubbo提供的线程池
    executor = (ExecutorService) ExtensionLoader.getExtensionLoader(ThreadPool.class).getAdaptiveExtension().getExecutor(url);

    String componentKey = Constants.EXECUTOR_SERVICE_COMPONENT_KEY;
    if (Constants.CONSUMER_SIDE.equalsIgnoreCase(url.getParameter(Constants.SIDE_KEY))) {
   
        componentKey = Constants.CONSUMER_SIDE;
    }
    DataStore dataStore = ExtensionLoader.getExtensionLoader(DataStore.class).getDefaultExtension();
    dataStore.put(componentKey, Integer.toString(url.getPort()), executor);
}


// 获取线程池
public ExecutorService getExecutorService() {
   
    ExecutorService cexecutor = executor;
    if (cexecutor == null || cexecutor.isShutdown()) {
   
        cexecutor = SHARED_EXECUTOR;
    }
    return cexecutor;
}
AllDispatcher

所有消息都派发到线程池,包括请求,响应,连接事件,断开事件,心跳等。
可以看到,这个dispatch的类,覆写了父类的所有方法,在子类的实现方法中,都是调用的cexecutor.execute()去提交的任务
getExecutorService()就是获取当前程序员配置的要使用的线程池,如果不配置,默认是fix

@Override
public void connected(Channel channel) throws RemotingException {
   
    ExecutorService cexecutor = getExecutorService();
    try {
   
        cexecutor.execute(new ChannelEventRunnable(channel, handler, ChannelState.CONNECTED));
    } catch (Throwable t) {
   
        throw new ExecutionException("connect event", channel, getClass() + &#
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值