这个问题抓得很关键,本质是在问:

为什么 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 直接调用
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐