Dubbo+Nacos
我用一个真实公司常见的电商系统例子讲,你会非常直观地理解 Dubbo + Nacos 为什么要一起用。
假设现在有一个电商系统。
一开始系统很小,所有功能都在一个项目里:
电商系统
├─ 用户模块
├─ 商品模块
├─ 订单模块
└─ 支付模块
代码之间调用非常简单:
orderService.createOrder()
userService.getUser()
payService.pay()
都是本地方法调用。
第一阶段:系统变大,必须拆微服务
随着用户变多,公司把系统拆成多个服务:
用户服务 user-service
商品服务 product-service
订单服务 order-service
支付服务 pay-service
每个服务都是:
一个独立 SpringBoot 项目
一个独立服务器
一个独立数据库
这时候问题来了:
订单服务创建订单时,需要:
1 获取用户信息
2 查询商品库存
3 调用支付
也就是:
订单服务
↓
调用 用户服务
调用 商品服务
调用 支付服务
但它们现在在不同服务器上。
第二阶段:使用 Dubbo 解决服务调用
这时 Dubbo 出场。
它的作用是:让远程调用像本地调用一样简单。
例如:
订单服务代码:
@DubboReference
UserService userService;
userService.getUser(id);
你写代码时感觉是:
调用本地方法
但实际上 Dubbo 在背后做了:
订单服务
↓
Dubbo代理
↓
网络通信(Netty)
↓
用户服务
所以 Dubbo 解决的是:服务之间怎么通信(RPC)。
第三阶段:服务越来越多,地址管理成问题
假设现在用户服务部署了 3 台服务器:
user-service
10.1.1.1:20880
10.1.1.2:20880
10.1.1.3:20880
订单服务如果直接写死:
10.1.1.1
就会有问题:
- 如果服务器宕机
- 如果新增服务器
- 如果IP改变
系统就会崩。
这时候就需要 注册中心。
第四阶段:使用 Nacos 作为注册中心
所有服务启动时都会注册到 Nacos:
user-service -> 注册
product-service -> 注册
order-service -> 注册
pay-service -> 注册
Nacos里就会有一个服务列表:
user-service
10.1.1.1:20880
10.1.1.2:20880
10.1.1.3:20880
第五阶段:调用流程
现在订单服务调用用户服务流程变成:
订单服务
↓
Dubbo询问 Nacos
↓
Nacos返回 user-service 地址列表
↓
Dubbo选择一个实例(负载均衡)
↓
RPC调用
比如:
order-service
↓
Nacos
↓
返回 3 个 user-service
↓
Dubbo选一个
↓
调用
如果某台服务器挂了:
Nacos 自动剔除
系统不会受影响。
第六阶段:Nacos还能做配置中心
Nacos不只是注册中心,还可以做配置管理。
例如:
数据库地址
Redis配置
开关配置
Dubbo参数
例如:
order.timeout=3000
pay.timeout=5000
服务启动时:
从 Nacos 拉取配置
这样就不需要:
application.yml 改配置再重启
可以动态更新。
最终架构(企业常见)
真实公司微服务架构通常是:
+----------------+
| Nacos |
|注册中心+配置中心|
+----------------+
↑ ↑
注册服务 获取地址
↑ ↑
+-------------+ +-------------+
| user-service| |order-service|
| Provider | | Consumer |
+-------------+ +-------------+
↑ |
|________Dubbo RPC_____|
一句话总结
企业微服务里通常是:
Dubbo 负责:服务调用 (RPC)
Nacos 负责:服务注册 + 配置管理
所以它们是:
合作关系
不是替代关系
如果你继续深入学 Java 微服务,你还会看到一种对比:
Dubbo + Nacos
vs
SpringCloud + OpenFeign + Nacos