Dubbo的实现原理
一句话概括
Dubbo 本质上是一个:
RPC框架 + 动态代理 + 注册中心 + 网络通信(Netty) + 负载均衡 + 服务治理它让远程调用看起来像本地方法调用。
例如:
userService.queryUser(1L);你以为是本地方法:
queryUser()实际上:
Consumer ↓ 网络传输 ↓ Provider ↓ 真正执行方法1 Dubbo整体架构
经典架构:
Registry (Nacos/ZK) ↑ ↓ Consumer ←→ Provider Netty通信角色:
Provider
服务提供者
@DubboService public class UserServiceImpl implements UserService { }启动时:
注册到注册中心Consumer
服务消费者
@DubboReference private UserService userService;调用:
userService.queryUser(1L);Registry
注册中心
常见:
- Apache ZooKeeper
- Nacos
负责:
服务注册 服务发现 地址变更通知2 服务启动过程
Provider启动
例如:
@DubboService public class UserServiceImplDubbo启动后:
第一步
扫描:
@DubboService第二步
生成服务URL
dubbo://10.1.1.10:20880第三步
注册到注册中心
/userService 10.1.1.10:20880Consumer启动
扫描:
@DubboReference private UserService userService;向注册中心订阅:
/userService得到:
10.1.1.10:20880 10.1.1.11:20880 10.1.1.12:20880缓存在本地。
3 调用过程(核心)
最经典面试题:
userService.queryUser() 为什么能调用远程服务?
第一步:生成代理对象
消费者启动时:
@DubboReference private UserService userService;Dubbo生成代理:
Proxy类似:
JDK Dynamic Proxy实际注入:
userService不是实现类。
而是:
Proxy对象第二步:拦截调用
调用:
userService.queryUser(1L);实际上进入:
InvocationHandler.invoke()收集:
接口名 方法名 参数 参数类型例如:
{ "service":"UserService", "method":"queryUser", "args":[1] }第三步:序列化
转成二进制:
Object ↓ byte[]常见:
Hessian2 FastJson2 Kryo Protobuf第四步:Netty发送
Dubbo底层使用:
Netty
建立:
TCP长连接发送:
Consumer ↓ Netty ↓ Provider4 Provider收到请求
Netty收到数据:
byte[]反序列化:
byte[] ↓ Invocation恢复:
queryUser(1L)反射调用:
UserServiceImpl.queryUser(1L)执行真实业务。
返回:
UserVO再次序列化:
UserVO ↓ byte[]通过Netty返回。
5 Consumer收到结果
收到:
byte[]反序列化:
UserVO返回给调用方:
UserVO user = userService.queryUser(1L);开发者感觉:
像本地调用其实是远程调用。
6 Dubbo为什么快
因为做了很多优化。
长连接
HTTP:
建立连接 发送 关闭连接Dubbo:
建立一次 重复使用即:
TCP长连接NIO
基于:
Netty
Reactor模型 + 事件驱动支持高并发。
高效序列化
比JSON更快:
Hessian2 Kryo Protobuf7 负载均衡
注册中心返回:
A B CConsumer选择一个。
默认:
Random随机。
Dubbo支持:
Random RoundRobin LeastActive ConsistentHash8 容错机制
Provider挂了:
A 挂 B 正常Consumer自动切换。
支持:
Failover Failfast Failsafe Failback Forking Broadcast最常用:
Failover失败重试。
9 Dubbo源码核心链路
调用:
userService.queryUser()↓
InvokerInvocationHandler.invoke()↓
MockClusterInvoker↓
FailoverClusterInvoker↓
LoadBalance↓
DubboInvoker↓
ExchangeClient↓
NettyClient↓
网络传输面试版总结
如果面试官问:
Dubbo实现原理是什么?
可以回答:
Dubbo 是一个基于 RPC 的分布式服务框架。服务提供者启动后会将服务地址注册到注册中心,服务消费者从注册中心订阅服务并获得提供者列表。
消费者通过 Dubbo 生成的动态代理对象发起调用,代理会将接口名、方法名和参数封装成 RPC 请求,经过序列化后通过 Netty 长连接发送到服务提供者。
提供者收到请求后反序列化,通过反射调用目标方法,执行结果再经过序列化返回给消费者。消费者反序列化后得到最终结果,整个过程对业务代码透明,看起来像本地方法调用。
Dubbo 底层核心技术包括动态代理、Netty、序列化、注册中心、负载均衡、集群容错以及 SPI 扩展机制。
Dubbo = 动态代理 + 注册中心 + Netty + 负载均衡 + 集群容错