去年公司接了个电商项目,用户量上来之后,单体架构扛不住了。订单、商品、库存全挤在一个应用里,改个字段都要全员联调,上线像打仗。我们决定用 Dubbo 搬家,把系统拆成几个独立服务。
为什么选 Dubbo 做服务发现
一开始也考虑过 Spring Cloud,但团队对 Java 和 RPC 更熟,Dubbo 的性能和稳定性在内部系统用过几次,心里有底。关键是它服务发现机制够轻,配合 ZooKeeper,服务一启动自动注册,下线也能感知,不用手动维护 IP 表。
比如订单服务要调库存,以前是写死 URL 调 HTTP 接口,现在只要在接口上打个 @DubboReference 注解,框架自己去注册中心找可用节点。
@Service
public class OrderServiceImpl implements OrderService {
@DubboReference
private StockService stockService;
public boolean createOrder(Order order) {
// 直接调用,服务发现由 Dubbo 完成
boolean available = stockService.deduct(order.getProductId(), order.getQuantity());
if (available) {
// 创建订单逻辑
return true;
}
return false;
}
}
注册中心怎么搭
我们用的是 ZooKeeper,三台机器搭个小集群,避免单点。每个 Dubbo 服务启动时,都会把自己的接口、IP、端口写到 ZK 的 /dubbo 节点下。消费者订阅这些路径,一旦有变动,ZK 就推通知,刷新本地缓存。
配置也不复杂,在 application.yml 里加上:
dubbo:
application:
name: order-service
registry:
address: zookeeper://192.168.1.10:2181
protocol:
name: dubbo
port: 20880
遇到的坑和解法
刚上线那会儿,测试环境老报“找不到提供者”。查下来是网络隔离,ZK 能连上,但服务之间的 Dubbo 端口没开。防火墙一放行,立马通了。
还有一次生产问题,某个库存实例挂了但没及时下线,消费方还在往它发请求。后来加了心跳检测和超时重试,设置 check=false 避免启动时报错:
@DubboReference(check = false, timeout = 3000, retries = 2)
现在用起来啥感觉
服务多了,但运维反而轻松了。加机器不用改配置,服务自己注册上去就行。开发也方便,谁要用哪个功能,看接口文档直接引用,不用等对方打包部署。
就像小区里的快递柜,你把包裹放进去,系统自动通知收件人来取。不用打电话约时间,也不会丢件。Dubbo 的服务发现,干的就是这个事。