先上原理图
-----Dubbo中的RPC实现原理源码分析----
一、注册与订阅过程---都是和zk交互
在每个zk客户端(生产者和消费者)启动时,会调用zk注册类的构造函数,初始化就监听连接事件:
分为注册与订阅两种连接事件。
1)注册----provider如何注册服务到zookeeper;
加上注解后,启动会从ServiceBean进入,仔细跟代码,最后会走到创建zk持久节点和临时节点的方法。节点创建会被zk客户端监听到。
调用链为RegistryProtocol#doRefer–>RegistryProtocol#doRefer–>FailbackRegistry#register–>FailbackRegistry#doRegister–>ZookeeperRegistry#doRegister–>zkClient#create
同时,会把服务放进暴露的服务列表中
2)订阅----consumer如何从zookeeper拉取provider信息;
消费者一样,需要去zk上注册节点,此为订阅。
调用链为RegistryProtocol#doRefer–>RegistryProtocol#doRefer–>FailbackRegistry#register–>FailbackRegistry#doRegister–>ZookeeperRegistry#doRegister–>zkClient#create
二、rpc请求过程---异步+Netty长连接
异步:每个RPC请求线程A都有一个唯一的id,封装在future对象中。
RPC请求的时候,会将此id也发送给provider,然后线程A会lock等待;
provider处理完请求后会将此id和返回结果一同返回给consumer;
consumer收到返回信息以后解析出id,找到对应的请求线程A,激活线程A,返回结果。
单一Netty长连接:上面的异步过程是每一个调用业务线程A,它们只进行到调用提供者时,就进入lock了。真正去调用提供者的是一个多个线程A共享的一个单一Netty长连接。Netty本身是异步的,只是通过监听回调实现了同步。
客户端接收到服务端的RPC调用响应,从底层到顶层依次是NettyClient获取NettyServer的响应,NettyClient将响应向上传递给HeaderExchangeHandler的received方法: