Dubbo 学习笔记
基于 3 台云服务器集群实战整理(5 课,文中 IP 均为示例,已脱敏)
版本:Dubbo 3.2.15 + Spring Boot 2.7.18 + Java 17
文档目录:
docs/dubbo-学习笔记.md(博客发布时拷贝docs/目录即可)
示例 IP 对照表
| 节点 | 公网 IP(SSH 示例) | 内网 IP | 典型角色 |
|---|---|---|---|
| Server 1 | 203.0.113.11 | 10.0.1.11 | Provider |
| Server 2 | 203.0.113.12 | 10.0.1.12 | Consumer |
| Server 3 | 203.0.113.13 | 10.0.1.13 | Provider 副本 |
一、Dubbo 是什么?
白话 :Java RPC 框架 ------像 打电话 ,Consumer 调接口,Provider 远程执行并 同步返回。
比喻:
- Provider = 接电话的店员(真正干活)
- Consumer = 顾客(发起调用)
- Registry(ZK) = 电话簿(查 Provider 地址)
- Protocol / Port = 分机号(如 20880、20881)
与 Kafka 对比:
| Dubbo | Kafka | |
|---|---|---|
| 模式 | 同步 RPC | 异步消息 |
| 发现方式 | ZK 注册中心 | Topic + Broker |
| 典型场景 | 查订单、创建订单(要立刻知道结果) | 订单事件通知库存/短信 |
二、本集群环境
2.1 三台机器分工
| 名称 | 公网 IP(SSH) | 内网 IP | 角色 |
|---|---|---|---|
| Server 1 | 203.0.113.11 |
10.0.1.11 | Provider 主节点 |
| Server 2 | 203.0.113.12 |
10.0.1.12 | Consumer |
| Server 3 | 203.0.113.13 |
10.0.1.13 | Provider 副本(负载均衡课) |
2.2 注册中心(ZooKeeper)
zookeeper://10.0.1.11:2181?backup=10.0.1.12,10.0.1.13
2.3 项目与部署路径
| 项目 | 路径(示例) |
|---|---|
| 学习笔记 | docs/ |
| 本地源码 | ~/projects/dubbo-demo/ |
| 服务器部署(原生 API) | /opt/dubbo-demo/java-demo/ |
| 服务器部署(Spring Boot) | /opt/dubbo-demo/spring-boot/ |
2.4 端口规划
| 服务 | 端口 | 应用名 |
|---|---|---|
| 原生 Provider | 20880 | dubbo-provider |
| Spring Boot Provider | 20881 | dubbo-spring-provider |
20880 公网通常不通(安全组),内网 RPC 正常。
2.5 Java 17 必加参数
bash
--add-opens java.base/java.math=ALL-UNNAMED
--add-opens java.base/java.lang=ALL-UNNAMED
三、五课知识地图
| 课次 | 主题 | 核心要点 |
|---|---|---|
| 第 1 课 | 原生 Java API | ServiceConfig.export()、ReferenceConfig.get() |
| 第 2 课 | Spring Boot | @DubboService、@DubboReference、application.yml |
| 第 3 课 | 多 Provider + 负载均衡 | ZK 多地址、loadbalance=roundrobin |
| 第 4 课 | 超时、重试、容错 | timeout、retries、failover / failfast |
| 第 5 课 | Dubbo + Kafka | 同步下单 + 异步 order-events |
四、第 1 课:原生 Java API
4.1 核心类对照
| 类 | 作用 |
|---|---|
ApplicationConfig |
应用名 |
RegistryConfig |
注册中心(ZK) |
ProtocolConfig |
协议与端口 |
ServiceConfig |
Provider 暴露服务 |
ReferenceConfig |
Consumer 引用服务 |
4.2 Provider 流程
java
ServiceConfig<DemoService> service = new ServiceConfig<>();
service.setInterface(DemoService.class);
service.setRef(new DemoServiceImpl());
service.export(); // 监听端口 + 注册 ZK
4.3 Consumer 流程
java
ReferenceConfig<DemoService> ref = new ReferenceConfig<>();
ref.setInterface(DemoService.class);
DemoService proxy = ref.get(); // 动态代理,非本地实现
proxy.sayHello("xxx"); // 远程 RPC
4.4 启动命令
bash
# Provider(Server 1)
java --add-opens java.base/java.math=ALL-UNNAMED \
--add-opens java.base/java.lang=ALL-UNNAMED \
-cp /opt/dubbo-demo/java-demo/target/dubbo-java-demo-1.0.0.jar \
org.demo.Provider
# Consumer(Server 2)
java --add-opens java.base/java.math=ALL-UNNAMED \
--add-opens java.base/java.lang=ALL-UNNAMED \
-cp /opt/dubbo-demo/java-demo/target/dubbo-java-demo-1.0.0.jar \
org.demo.Consumer
五、第 2 课:Spring Boot 版
5.1 项目结构
spring-boot/
├── dubbo-api/ # 公共接口(DemoService、OrderService)
├── provider/ # @DubboService 实现
└── consumer/ # @DubboReference 调用
5.2 注解对照
| 原生 API | Spring Boot |
|---|---|
ServiceConfig.export() |
@DubboService |
ReferenceConfig.get() |
@DubboReference |
| 手动 new Config | application.yml + @EnableDubbo |
5.3 Provider 配置示例
yaml
dubbo:
application:
name: dubbo-spring-provider
registry:
address: zookeeper://10.0.1.11:2181?backup=10.0.1.12,10.0.1.13
protocol:
name: dubbo
port: 20881
qos:
enable: false
5.4 打包与运行
bash
cd /opt/dubbo-demo/spring-boot
mvn clean package -DskipTests
java --add-opens java.base/java.math=ALL-UNNAMED \
--add-opens java.base/java.lang=ALL-UNNAMED \
-jar provider/target/dubbo-spring-provider-1.0.0.jar
java ... -jar consumer/target/dubbo-spring-consumer-1.0.0.jar
六、第 3 课:负载均衡
6.1 多 Provider 注册
两台 Provider 同接口、同应用名 → ZK 里 多个地址:
/services/dubbo-spring-provider
→ [10.0.1.11:20881, 10.0.1.13:20881]
6.2 负载均衡策略
| 策略 | 说明 |
|---|---|
| random(默认) | 随机 |
| roundrobin | 轮询(本课演示用) |
| leastactive | 选最闲的 |
| consistenthash | 相同参数总打同一台 |
yaml
dubbo:
consumer:
loadbalance: roundrobin
或:
java
@DubboReference(loadbalance = "roundrobin")
6.3 故障切换
一台 Provider 挂了 → Consumer 自动只用存活节点(第 3 课实验:停 Server 3,12 次全落 Server 1)。
七、第 4 课:超时与容错
7.1 timeout
java
@DubboReference(timeout = 2000) // 毫秒,超时抛 TimeoutException
Provider 5 秒才返回、timeout 2 秒 → RpcException / TimeoutException。
7.2 retries + cluster
| 配置 | 含义 |
|---|---|
retries=2 |
失败后最多再试 2 次 |
cluster=failover(默认) |
失败 换节点 重试 |
cluster=failfast |
失败 立刻报错,不重试 |
7.3 策略选择
| 场景 | 推荐 |
|---|---|
| 读操作、可重试 | failover + 适当 retries |
| 写操作、下单扣款 | failfast + retries=0 |
7.4 实验结论
- failover :打到慢节点(Server 3)超时后,换 Server 1 重试 → 仍可能成功
- failfast :打到慢节点 → 3 秒超时直接失败,不重试
八、第 5 课:Dubbo + Kafka
8.1 架构
Consumer --Dubbo RPC--> OrderServiceImpl(Provider)
│
├── 同步返回 orderId
└── Kafka send → order-events
8.2 OrderService 接口
java
public interface OrderService {
String createOrder(String productName, double amount);
}
8.3 Provider 核心逻辑
- 生成
orderId - Dubbo 同步返回 给 Consumer
- Kafka 异步发送
ORDER_CREATED|...到order-events
8.4 Consumer 配置
java
@DubboReference(cluster = "failfast", retries = 0)
private OrderService orderService;
8.5 验证 Kafka 事件
bash
/opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server 10.0.1.11:9092 \
--topic order-events \
--from-beginning
九、ZK 排查 Dubbo 注册
bash
# 应用级
/opt/kafka/bin/zookeeper-shell.sh 10.0.1.11:2181 \
ls /services/dubbo-spring-provider
# 接口级
/opt/kafka/bin/zookeeper-shell.sh 10.0.1.11:2181 \
ls /dubbo/org.demo.DemoService/providers
十、常见问题
| 问题 | 处理 |
|---|---|
| Java 17 序列化报错 | 加 --add-opens |
| Spring Boot 缺 ZK 客户端 | 依赖 dubbo-registry-zookeeper |
| qos 端口 22222 冲突 | dubbo.qos.enable: false |
| Consumer 找不到 Provider | 查 ZK、查 Provider 进程、查防火墙 |
| 公网连不上 20880 | 正常,用内网 IP |
| 接口不一致 | 确保 dubbo-api 模块 Provider/Consumer 共用 |
十一、依赖清单(Spring Boot Provider)
xml
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-zookeeper</artifactId>
</dependency>
<!-- 第 5 课 Kafka -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>3.6.2</version>
</dependency>
十二、命令速查(SSH)
powershell
# 示例:使用你的密钥与公网 IP 连接 Server 2
ssh -i ~/.ssh/your-key.pem root@203.0.113.12
bash
# Spring Consumer(Server 2)
java --add-opens java.base/java.math=ALL-UNNAMED \
--add-opens java.base/java.lang=ALL-UNNAMED \
-jar /opt/dubbo-demo/dubbo-spring-consumer-1.0.0.jar
# Spring Provider(Server 1)
java --add-opens java.base/java.math=ALL-UNNAMED \
--add-opens java.base/java.lang=ALL-UNNAMED \
-jar /opt/dubbo-demo/spring-boot/provider/target/dubbo-spring-provider-1.0.0.jar
十三、一句话总结
Dubbo = 同步 RPC + 服务治理 :Provider 暴露接口、ZK 注册发现、Consumer 远程调用;配合 负载均衡、超时容错 保证高可用;与 Kafka 组合时 Dubbo 负责 同步业务 ,Kafka 负责 异步事件。