1 dubbo源码的整体路数
-
监听器启动初始化刷新配置
-
通过SPI导入Protocol
-
通过Protocol实现和注册中心的信息同步(暴露、引入、注册、订阅服务)
-
通过Registery和注册中心进行信息的同步
-
最后在交换层实现信息的发送或者zk客户端和zk服务进行交互
暴露、引入、注册、订阅服务整体的屌用流程有个共同点:
- SPI引入Protocol、暴露服务或引入服务Protocol分别和Registry交换或者交换层进行交互
- 所以Protocol在代码执行过程中是个中枢的位置,大部分的执行都会执行Protocol
- 而且其扩展线都是在DubboSPI的基础上进行扩展的
2 服务暴露
- Listener启动、Deployerk开启初始化
- export导出服务
- Protocol导出服务
- 和ZkClient进行交互创建zk节点
3 服务端处理各种事件的模型
链接、序列化反序列化、读取消息、发送消息等事件
四种线程处理模型,可能有点绕。单纯的看代码获取有点和官网解说的不太一样,但是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
- 一种情况是返货一个是ThreadlessExecutor的线程池,这是一个Dubbo定制的线程池,使用的是原始事件分配的线程池也就是IO线程。
- 返回的是非ThreadlessExecutor的线程池,也就是Dubbo共享业务线程池,但是在非ThreadlessExecutor的线程池情况,走的是直接执行的方式没有线程池执行,也就是IO线程池
- 所以总结一下就是虽然获取啦线程池,无论是不是ThreadlessExecutor线程池都会使用Netty的IO线程执行,看着挺唬人的走啦个线程池。
所有的执行时间都是在Netty IO线程执行。
还有Execution、Message、Connection三种线程模型之后再分析吧,大同小异,都是通过操作获取线程池的类型来操控从那个线程池上执行事件的
4 后续
消费端的线程模型