为什么 Dubbo 不像 Feign 一样拼 URL,而是用 Invoker?
·
这个问题抓得很关键,本质是在问:
为什么 Dubbo 不像 Feign 一样拼 URL,而是用 Invoker?
答案核心一句话:
Dubbo 是 RPC 框架,目标是“方法调用”,不是“HTTP资源定位”
一、先对比本质差异
Feign(HTTP思维)
URL = 资源定位
例如:
http://10.0.0.1:8080/user/1
必须有:
- IP
- port
- path
👉 因为 HTTP 天生就是“URL寻址模型”
Dubbo(RPC思维)
调用 = 方法调用
例如:
userService.queryUser(1L)
目标不是 URL,而是:
调用哪个“服务实例 + 方法”
二、Invoker 是什么(核心)
Invoker 不是 URL,而是:
对“远程服务提供者”的抽象封装
可以理解为:
class Invoker {
URL url;
invoke(MethodInvocation)
}
但重点是:
Invoker = “可执行的远程调用对象”
三、为什么 Dubbo 不直接用 URL?
1. URL 只表达“地址”,不表达“能力”
URL只能表示:
http://10.0.0.1:8080
但 Dubbo 需要:
1. 接口
2. 方法
3. 参数类型
4. 序列化方式
5. 超时
6. 重试策略
7. 版本
8. 分组
这些 URL 根本表达不了。
2. Dubbo是“方法级RPC”,不是“HTTP资源访问”
Feign:
GET /user/1
Dubbo:
UserService.queryUser(Long id)
👉 这是“方法调用模型”,不是“URL访问模型”
3. Invoker = 完整调用上下文
一个 Invoker 实际包含:
IP + Port
接口信息
方法元数据
序列化协议
超时
负载均衡标识
路由规则
URL太“单薄”,承载不了这些。
四、Dubbo调用时到底发生了什么?
1. 启动阶段
Provider:
UserService → 10.0.0.1:20880
Consumer:
从注册中心拿到 Invoker 列表
2. 本地结构
List<Invoker> = [
Invoker(10.0.0.1:20880),
Invoker(10.0.0.2:20880)
]
3. 调用阶段(关键)
userService.queryUser(1L);
流程:
动态代理
↓
InvocationHandler
↓
InvokerList
↓
LoadBalance选Invoker
↓
invoke()
↓
Netty发送
4. 注意关键点
👉 Dubbo最终做的是:
不是“拼URL”
而是:
调用 Invoker.invoke()
五、如果强行用URL会有什么问题?
问题1:RPC能力表达不足
timeout=100ms
retries=3
version=1.0
group=gray
URL表达不了。
问题2:治理能力无法插入
Dubbo需要:
负载均衡
路由
熔断
降级
mock
这些都发生在 Invoker 层。
问题3:性能问题
URL模型 = HTTP语义
解析URL → HTTP协议 → header → JSON
Dubbo:
直接序列化对象 → TCP → Netty
更轻。
六、Invoker设计的本质(最重要)
一句话:
Invoker = 把“远程方法调用”抽象成“可执行对象”
它的作用是:
屏蔽网络 + 协议 + 注册中心差异
让上层只关心:
调用哪个服务 + 调哪个方法
七、Dubbo vs Feign 本质对比
| 维度 | Dubbo | Feign |
|---|---|---|
| 思维模型 | RPC(方法调用) | HTTP(资源访问) |
| 地址形式 | Invoker | URL |
| 路由单位 | 服务 + 方法 | HTTP路径 |
| 通信协议 | TCP | HTTP |
| 核心抽象 | Invoker | ServiceInstance |
八、面试标准回答
可以这样说:
Dubbo 不使用 URL,是因为它是 RPC 框架,其核心目标是实现“方法级调用”,而不是 HTTP 资源访问。URL 只能表达网络地址,但无法表达接口、方法、参数类型、超时、重试等丰富的RPC元数据。
因此 Dubbo 抽象出 Invoker 作为核心调用模型,Invoker 不仅包含服务地址,还封装了调用能力和协议细节。调用时通过动态代理进入 InvocationHandler,再通过 LoadBalance 从 Invoker 列表中选择一个具体实例,直接执行 invoke 方法完成远程调用。
本质上,Dubbo 是“面向方法的分布式调用模型”,而 Feign 是“面向HTTP URL的请求模型”。
一句话总结
Feign:找到 URL 去请求
Dubbo:找到 Invoker 直接调用更多推荐

所有评论(0)