Dubbo 服务端暴露服务、处理消息(03)

1 dubbo源码的整体路数

  • 监听器启动初始化刷新配置

  • 通过SPI导入Protocol

  • 通过Protocol实现和注册中心的信息同步(暴露、引入、注册、订阅服务)

  • 通过Registery和注册中心进行信息的同步

  • 最后在交换层实现信息的发送或者zk客户端和zk服务进行交互

暴露、引入、注册、订阅服务整体的屌用流程有个共同点:

  1. SPI引入Protocol、暴露服务或引入服务Protocol分别和Registry交换或者交换层进行交互
  2. 所以Protocol在代码执行过程中是个中枢的位置,大部分的执行都会执行Protocol
  3. 而且其扩展线都是在DubboSPI的基础上进行扩展的

2 服务暴露

  1.  Listener启动、Deployerk开启初始化
  2. export导出服务
  3. Protocol导出服务
  4. 和ZkClient进行交互创建zk节点

3 服务端处理各种事件的模型

参考链接:https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/threading-model/provider/

链接、序列化反序列化、读取消息、发送消息等事件

四种线程处理模型,可能有点绕。单纯的看代码获取有点和官网解说的不太一样,但是debug一下还是可以看明白的。

1 AllDispacher模型

针对链接、断开链接、接受消息、异常事件都会分配到业务线程池中


public class AllChannelHandler extends WrappedChannelHandler {

    public AllChannelHandler(ChannelHandler handler, URL url) {
        super(handler, url);
    }

    @Override
    public void connected(Channel channel) throws RemotingException {
        ExecutorService executor = getSharedExecutorService();
        try {
            executor.execute(new ChannelEventRunnable(channel, handler, ChannelState.CONNECTED));
        } catch (Throwable t) {
            throw new ExecutionException("connect event", channel, getClass() + " error when process connected event .", t);
        }
    }

    @Override
    public void disconnected(Channel channel) throws RemotingException {
        ExecutorService executor = getSharedExecutorService();
        try {
            executor.execute(new ChannelEventRunnable(channel, handler, ChannelState.DISCONNECTED));
        } catch (Throwable t) {
            throw new ExecutionException("disconnect event", channel, getClass() + " error when process disconnected event .", t);
        }
    }

    @Override
    public void received(Channel channel, Object message) throws RemotingException {
        ExecutorService executor = getPreferredExecutorService(message);
        try {
            executor.execute(new ChannelEventRunnable(channel, handler, ChannelState.RECEIVED, message));
        } catch (Throwable t) {
            if(message instanceof Request && t instanceof RejectedExecutionException){
                sendFeedback(channel, (Request) message, t);
                return;
            }
            throw new ExecutionException(message, channel, getClass() + " error when process received event .", t);
        }
    }

    @Override
    public void caught(Channel channel, Throwable exception) throws RemotingException {
        ExecutorService executor = getSharedExecutorService();
        try {
            executor.execute(new ChannelEventRunnable(channel, handler, ChannelState.CAUGHT, exception));
        } catch (Throwable t) {
            throw new ExecutionException("caught event", channel, getClass() + " error when process caught event .", t);
        }
    }



}

2 Direct 模型

在DirectHandler中有个获取线程池的方法,这个方法看着挺迷惑,实际效果是没走该线程池,就算走的是该线程池世纪效果也是走的IO线程池中的线程。

先从获取线程池的的方法查看 getPreferredExecutorService

  1. 一种情况是返货一个是ThreadlessExecutor的线程池,这是一个Dubbo定制的线程池,使用的是原始事件分配的线程池也就是IO线程。
  2. 返回的是非ThreadlessExecutor的线程池,也就是Dubbo共享业务线程池,但是在非ThreadlessExecutor的线程池情况,走的是直接执行的方式没有线程池执行,也就是IO线程池
  3. 所以总结一下就是虽然获取啦线程池,无论是不是ThreadlessExecutor线程池都会使用Netty的IO线程执行,看着挺唬人的走啦个线程池。

所有的执行时间都是在Netty IO线程执行。

还有Execution、Message、Connection三种线程模型之后再分析吧,大同小异,都是通过操作获取线程池的类型来操控从那个线程池上执行事件的

4 后续

消费端的线程模型

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值