基于SpringBoot和Dubbo的分布式服务架构实现服务远程调用
1. 项目概述
1.1 项目简介
本项目是一个基于Apache Dubbo 3.x和Spring Boot 2.x的分布式服务架构示例,展示了 Dubbo 服务治理的核心能力。
1.2 技术栈
| 组件 | 版本 | 说明 |
|---|---|---|
| Java | 17 | 编程语言 |
| Spring Boot | 2.7.6 | 应用框架 |
| Apache Dubbo | 3.2.11 | 分布式服务框架 |
| ZooKeeper | 3.x+ | 服务注册中心 |
| Lombok | 1.18.x | 代码简化工具 |
1.3 架构设计
┌─────────────────────────────────────────────────────────────────┐ │ ZooKeeper Registry │ │ (127.0.0.1:2181) │ └───────────────────┬─────────────────────────────────────────────┘ │ ┌───────────┴───────────┐ │ │ ▼ ▼ ┌───────────────┐ ┌───────────────┐ │ Provider │ │ Consumer │ │ (20880) │ │ (8081) │ └───────┬───────┘ └───────┬───────┘ │ │ ▼ ▼ ┌───────────────┐ ┌───────────────┐ │UserServiceImpl│ │UserController │ └───────┬───────┘ └───────┬───────┘ │ │ └───────────┬───────────┘ │ ▼ ┌───────────────────┐ │ UserService API │ │ User (POJO) │ └───────────────────┘流程图
图中流程说明:
Provider 启动后,UserServiceImpl 将自己的元数据(地址、端口、接口)注册到 ZooKeeper。
Consumer启动时,UserService API(实际是 Dubbo 生成的代理)从 ZooKeeper 获取 Provider 地址列表。
UserController 调用 UserService API 时,代理对象通过 Dubbo 协议 发起RPC远程调用到UserServiceImpl,过程中可能用到 User POJO 进行参数序列化/反序列化。
Provider会定期向ZooKeeper 发送心跳,保持注册信息的活性。
2. 模块划分
2.1 模块结构
| 模块 | 职责 | 类型 |
|---|---|---|
| dubbo-service-api | 定义服务接口和数据模型 | 公共依赖 |
| dubbo-service-provider | 实现服务接口,暴露 Dubbo 服务 | 服务端 |
| dubbo-service-consumer | 消费远程服务,对外提供 REST API | 消费端 |
2.2 目录结构
dubbo-springboot/ ├── pom.xml # 父工程配置 ├── dubbo-service-api/ # 服务接口模块 │ ├── pom.xml │ └── src/main/java/com/weh/ │ ├── pojo/User.java # 用户实体类 │ └── service/UserService.java # 服务接口 ├── dubbo-service-provider/ # 服务提供者 │ ├── pom.xml │ └── src/main/ │ ├── java/com/weh/ │ │ ├── ServiceProviderApplication.java # 启动类 │ │ └── service/impl/UserServiceImpl.java # 服务实现 │ └── resources/application.yml # 配置文件 └── dubbo-service-consumer/ # 服务消费者 ├── pom.xml └── src/main/ ├── java/com/weh/ │ ├── ServiceConsumerApplication.java # 启动类 │ └── controller/UserController.java # REST控制器 └── resources/application.yml # 配置文件3. 核心代码详解
父工程配置主要依赖
<modules><module>dubbo-service-api</module><module>dubbo-service-provider</module><module>dubbo-service-consumer</module></modules><properties><java.version>17</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.7.6</spring-boot.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- Dubbo Spring Boot Starter (核心) --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>3.2.11</version></dependency><!-- Dubbo 3.x 推荐直接使用 dubbo-registry-zookeeper,无需额外引入 zkclient/curator 冲突包 --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-registry-zookeeper</artifactId><version>3.2.11</version></dependency></dependencies>3.1 实体类定义
文件路径:dubbo-service-api/src/main/java/com/weh/pojo/User.java
@DatapublicclassUserimplementsSerializable{privatestaticfinallongserialVersionUID=1L;privateLongid;// 用户IDprivateStringname;// 用户名称privateIntegerage;// 用户年龄}设计要点:
- 必须实现
Serializable接口,支持 Dubbo 序列化传输 - 使用
@Data注解自动生成 getter/setter 方法
3.2 服务接口定义
文件路径:dubbo-service-api/src/main/java/com/weh/service/UserService.java
publicinterfaceUserService{/** * 根据ID查询用户 * @param id 用户ID * @return 用户对象,不存在返回null */UsergetUserById(Longid);}3.3 服务提供者实现
文件路径:dubbo-service-provider/src/main/java/com/weh/service/impl/UserServiceImpl.java
@DubboService// 暴露为 Dubbo 服务publicclassUserServiceImplimplementsUserService{@OverridepublicUsergetUserById(Longid){Useruser=newUser();user.setId(1L);user.setName("张三");user.setAge(18);returnid==1L?user:null;}}关键注解:
@DubboService:将服务注册到 Dubbo,等价于传统 Dubbo 的<dubbo:service>配置
3.4 服务消费者控制器
文件路径:dubbo-service-consumer/src/main/java/com/weh/controller/UserController.java
@RestController@RequestMapping("/user")publicclassUserController{@DubboReference(mock="return null")// 引用远程服务privateUserServiceuserService;@RequestMapping("/findOne/{id}")publicStringfindOne(@PathVariableLongid,Modelmodel){Useruser=userService.getUserById(id);returnuser!=null?user.toString():"null";}}关键注解:
@DubboReference:注入远程服务代理,等价于传统 Dubbo 的<dubbo:reference>配置mock = "return null":服务调用失败时返回 null,不抛出异常
4. 配置说明
4.1 提供者配置
文件路径:dubbo-service-provider/src/main/resources/application.yml
dubbo:application:name:service-provider# 服务名称register-mode:interface# 接口级注册模式scan:base-packages:com.weh.service.impl# 扫描服务实现包protocol:name:dubbo# 协议名称port:20880# 服务端口registry:address:zookeeper://127.0.0.1:2181# 注册中心地址use-as-config-center:false# 不使用作为配置中心use-as-metadata-center:false# 不使用作为元数据中心provider:timeout:5000# 服务超时时间4.2 消费者配置
文件路径:dubbo-service-consumer/src/main/resources/application.yml
server:port:8081# 应用端口dubbo:application:name:service-consumer# 消费者名称register-mode:interfaceqos-enable:true# 启用 QOS 服务qos-port:33333# QOS 端口qos-accept-foreign-ip:false# 拒绝外部IP访问 QOSregistry:address:zookeeper://127.0.0.1:2181use-as-config-center:falseuse-as-metadata-center:falseconsumer:check:false# 启动时不检查服务是否存在provider:timeout:50005. 启动与运行
5.1 前置条件
- 安装并启动 ZooKeeper(默认端口 2181)
- 确保 JDK 17 环境已配置
5.2 启动顺序
# 1. 启动 ZooKeeperzkServer.sh start# Linux/MaczkServer.cmd start# Windows# 2. 编译项目(在根目录执行)mvn cleaninstall-DskipTests# 3. 启动服务提供者cddubbo-service-provider mvn spring-boot:run# 4. 启动服务消费者(新终端)cddubbo-service-consumer mvn spring-boot:run5.3 服务验证
访问 REST API 测试服务调用:
# 测试正常请求curlhttp://localhost:8081/user/findOne/1# 响应:User(id=1, name=张三, age=18)# 测试不存在的用户curlhttp://localhost:8081/user/findOne/2# 响应:null6. Dubbo 核心特性说明
| 特性 | 说明 | 本项目配置 |
|---|---|---|
| 服务注册与发现 | 通过 ZooKeeper 实现服务自动注册和发现 | registry.address |
| 协议支持 | 默认使用 Dubbo 协议,高性能二进制传输 | protocol.name: dubbo |
| 服务治理 | 支持负载均衡、容错、降级等能力 | consumer.check: false |
| Mock 机制 | 服务不可用时的降级策略 | @DubboReference(mock) |
| QOS 控制台 | 提供服务治理命令行接口 | qos-enable: true |
7. Dubbo Admin 服务管理平台
Dubbo Admin 是 Apache Dubbo 官方提供的服务治理和管理平台,提供可视化的服务管理、配置管理、服务测试、流量治理等功能。
7.1 Dubbo Admin 简介
Dubbo Admin 主要功能包括:
- 服务查询:查看已注册的服务、提供者、消费者信息
- 服务治理:动态配置服务参数(超时、重试、负载均衡等)
- 流量治理:路由规则、标签路由、权重调整
- 配置管理:动态修改应用配置
- 服务测试:在线测试 Dubbo 服务接口
- 元数据管理:查看服务元数据信息
7.2 安装与启动
方式一:Docker 快速启动(推荐)
# 拉取最新版 Dubbo Admindockerpull apache/dubbo-admin:0.6.0# 运行容器dockerrun-d\--namedubbo-admin\-p38080:38080\-eadmin.registry.address=zookeeper://127.0.0.1:2181\-eadmin.config-center=zookeeper://127.0.0.1:2181\-eadmin.metadata-report.address=zookeeper://127.0.0.1:2181\apache/dubbo-admin:0.6.0方式二:源码编译运行
# 克隆源码gitclone https://github.com/apache/dubbo-admin.git# 进入目录cddubbo-admin# 修改配置文件(application.yml)# 将 registry.address 改为自己的 ZooKeeper 地址# 编译运行(注意:从 0.6.0 版本开始,Dubbo Admin 已重构为前后端分离架构)mvn clean package-DskipTests# 启动后端服务java-jardubbo-admin-server/target/dubbo-admin-server-*.jar# vue前端需要单独启动(或使用预编译的静态资源)dubbo-admin-ui7.3 访问与配置
版本兼容性说明:
- Dubbo Admin 0.8.0:支持 Dubbo 3.x,推荐与 Dubbo 3.2.x 配合使用
- Dubbo Admin 0.7.0:支持 Dubbo 3.0.x - 3.1.x
- Dubbo Admin 0.6.0:架构重构,前后端分离,支持更多治理功能
最新版本特性(0.8.0):
- 全新 UI 界面:基于 Vue 3 + Element Plus 重构
- 增强的流量治理:支持更细粒度的路由规则
- 多注册中心支持:同时管理 ZooKeeper、Nacos、Consul 等
- 服务 Mock 测试:支持在线编写 Mock 规则
- 性能优化:减少内存占用,提升响应速度
# application.yml 关键配置dubbo:registry:address:zookeeper://127.0.0.1:2181# 注册中心地址config-center:address:zookeeper://127.0.0.1:2181# 配置中心地址metadata-report:address:zookeeper://127.0.0.1:2181# 元数据中心地址- 访问地址:
http://localhost:38080 - 默认账号:
root/root - 配置说明:
7.4 主要功能使用
7.4.1 服务查询
- 登录后进入服务治理 → 服务查询
- 可以看到已注册的服务列表:
com.weh.service.UserService(本项目定义的服务)- 提供者地址:
127.0.0.1:20880 - 消费者地址:
127.0.0.1:8081
7.4.2 动态配置
- 进入服务治理 → 动态配置
- 创建新配置:
configVersion:v2.7scope:applicationkey:service-consumerconfigs:-addresses:['0.0.0.0']parameters:timeout:3000# 将超时时间改为3秒retries:2# 重试次数7.4.3 服务测试
- 进入服务测试 → 服务测试
- 选择服务:
com.weh.service.UserService - 选择方法:
getUserById - 输入参数:
{"id": 1} - 点击执行,查看返回结果
7.4.4 流量治理
权重调整:进入流量治理 → 权重调整
- 可以调整不同提供者的流量权重
- 支持蓝绿发布、金丝雀发布
标签路由:进入流量治理 → 标签路由
- 根据标签将流量路由到特定提供者
- 实现环境隔离(dev/test/prod)
7.5 集成到本项目
7.5.1 修改消费者配置
在dubbo-service-consumer的application.yml中增加:
dubbo:application:qos-enable:true# 启用 QOS(必须开启)qos-port:33333# QOS 端口qos-accept-foreign-ip:true# 允许外部访问(Dubbo Admin 需要)7.5.2 验证集成
- 重启消费者应用
- 在 Dubbo Admin 中查看服务状态
- 测试服务调用是否正常
7.6 常见问题
Q1:Dubbo Admin 无法连接到服务?
- 检查 ZooKeeper 是否正常运行
- 检查应用是否开启了 QOS:
qos-enable: true - 检查防火墙是否开放了 QOS 端口
Q2:服务列表中看不到服务?
- 确认服务已成功注册到 ZooKeeper
- 检查 Dubbo Admin 的 registry.address 配置是否正确
- 查看应用日志是否有注册异常
Q3:动态配置不生效?
- 确认配置的 scope 和 key 正确
- 检查应用是否订阅了配置中心
- 查看配置是否推送到所有实例
7.7 最佳实践
生产环境部署:
- 使用独立部署的 ZooKeeper/Nacos 集群
- 为 Dubbo Admin 配置域名和 HTTPS
- 定期备份配置数据
权限管理:
- 修改默认密码
- 根据团队角色分配权限
- 开启操作日志审计
监控告警:
- 集成 Prometheus 监控 Dubbo Admin 自身
- 配置关键操作告警
- 定期检查服务健康状态
8. 扩展建议
- 增加服务监控:集成 Prometheus + Grafana 监控 Dubbo 服务指标
- 引入配置中心:使用 Nacos 替代 ZooKeeper 作为配置中心
- 增加单元测试:为服务实现添加测试用例
- 服务分组:通过
group属性实现服务多版本管理 - 负载均衡策略:配置
loadbalance属性选择合适的负载均衡算法