首先分享之前的所有文章 , 欢迎点赞收藏转发三连下次一定 >>>> 😜😜😜
文章合集 : 🎁 juejin.cn/post/694164…
Github : 👉 github.com/black-ant
CASE 备份 : 👉 gitee.com/antblack/ca…
一 . 前言
Dubbo 3.0 在去年就已经发布了 , 整体来说使用没有太大的区别 , 之前一直没有好好读一下 Dubbo 的源码 , 这里把这些补上 , 顺便来看看和 2.0 有什么区别.
Dubbo 2.0 中把 Dubbo 分成了 10 个层次 , 相对 3.0 同样如此 , 这一篇只要对应 Proxy , Exchange , Transport 三个部分
1.1 补充一 : RPC 简介
RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。
一个基本的RPC架构里面应该至少包含以下4个组件:
1、客户端(Client):服务调用方(服务消费者)
2、客户端存根(Client Stub):存放服务端地址信息,将客户端的请求参数数据信息打包成网络消息,再通过网络传输发送给服务端
3、服务端存根(Server Stub):接收客户端发送过来的请求消息并进行解包,然后再调用本地服务进行处理
4、服务端(Server):服务的真正提供者
Dubbo3 的核心内容之一就是定义了下一代 RPC 协议 , 除了通信功能 , 还具有以下的功能 :
- 统一的跨语言二进制格式
- 支持Streaming 和应用层全双工调用模型
- 易于扩展
- 能够被各层设备识别
二 . RPC Server 端
2.1 Service 服务类案例
以官方案例为例 , 先看一下 Service 端有什么关键点 :
1 | java复制代码@DubboService |
2.2 Server 端创建代理
忽略 @DubboService 的扫描逻辑 , 我们只是来看一下是怎么扫描和创建 Server 端的代理的
2.3 Server 端被调流程
该环节中将属性映射到对应的方法 , 主要看一下 Server 端的反射流程 :
- C- ChannelEventRunnable # run : 对 channel 监听和处理
- C- DecodeHandler # received : 接受消息
- C- HeaderExchangeHandler # received : Exchange 接收
- C- HeaderExchangeHandler # handleRequest : 处理请求
- C- DubboProtocol # requestHandler : 反射到指定的方法
- C- xxxFilter.invoke : Filter 拦截链处理
- C- InvokerWrapper # invoke
- C- AbstractProxyInvoker # invoke
- C- JavassistProxyFactory # doInvoke
这里可以看到 , 主体还是经过 Exchange - Protocol - Proxy 进行处理的
2.3.1 接收消息
在从 received 看之前 , 要先看一下 Dubbo Remote 远程调用的相关逻辑 , 可以看懂 ,入口类为ChannelEventRunnable :
补充 : ChannelEventRunnable 的注册
1 | java复制代码// ChannelEventRunnable 的注册是在调用时进行 , 首先构建了一个 NettyServerHandler 进行 Netty 服务器的创建 |
正式处理 : 看看 ChannelEventRunnable 如何实现监听分类
可以看到 , ChannelEventRunnable 中会针对不同的 state 去调用不同的逻辑
1 | java复制代码// 接收到数据 |
此处只关注 received , 代码和接收的数据如下
1 | JAVA复制代码// C- DecodeHandler # received : 接受消息 |
2.3.2 received 处理 request
先来看一下 ExchangeHandler 体系结构
这里在 DecodeHandler 中就先进行了一遍处理 , 分别通过 message 的类型 , 进行了一次 decode 处理 :
- Decodeable –> decode(message);
- Request –> decode(((Request) message).getData())
- Response –> decode(((Response) message).getResult());
然后才是 HeaderExchangeHandler 对 Channel 的请求的处理 :
1 | java复制代码C- HeaderExchangeHandler |
2.3.3 处理 Request , 构建 Response
因为 isTwoWay 为 true ,说明需要通过 response 告知调用者已经接收到消息
这里准备了 Response , 并且进行返回 , 同时调用对应方法
1 | java复制代码void handleRequest(final ExchangeChannel channel, Request req) throws RemotingException { |
2.3.4 获取反射到的方法
上面那个环节构建了一个 CompletableFuture , 此对象由 DubboProtocol # requestHandler 完成构建 :
1 | java复制代码C- DubboProtocol |
2.4 Filter 体系
之前看到 , 构建 invoke 的时候是构建 FilterChain , 感觉这种写法挺不错 , 以后有机会试试 , 这里的 Filter 主要有 :
- EchoFilter
- ClassLoaderFilter
- GenericFilter
- ContextFilter
- ExceptionFilter
- MonitorFilter
- TimeoutFilter
- TraceFilter
1 | java复制代码C- FilterChainBuilder |
2.5 最终的方法调用
以及最后一个Filter 的方法调用
1 | java复制代码C- AbstractProxyInvoker |
2.6 RPC 的 线程调用
RPC 被调流程中 , 创建的是 InternalRunnable , 来看一下是如何调用的
其底层是通过 Netty 进行的交互 , 这里就不详述了 ,以后说 Netty 时再分析
1 | java复制代码public class InternalRunnable implements Runnable{ |
三 . 深入梳理
3.1 方法的信息来源和校验
1 | java复制代码// 从 Netty 传入的参数是这样的 : |
总结
从这篇发现 , Dubbo 的 Method 代理信息是从远程 Client 传递过来的 ,而远程 Client 在启动时会校验 @ReferenceService 是否正确 , 从而保证了准确性
- Dubbo Server 端首先会创建 NettyService
- 处理的起点是 ChannelEventRunnable , 通过 DecodeHandler 进行解析
- 核心的处理逻辑在 DubboProtocol , 这个环节中已经获取具体的 Invoke 类了
- 最终的调用方为 JavassistProxyFactory , 发起代理的调用
整体来说 , 看 Dubbo 的代码还是更接地气 , 比看 Spring 的代码收获了更多的东西 !!!!!!!!!!
本文转载自: 掘金