混合架构(SpringCloud+Dubbo)的整合方案与适用场景(二)
二、混合架构(SpringCloud+Dubbo)整合方案(实战落地)
2.1 核心整合思路:“分工明确,优势互补”
通过分层架构设计,让 SpringCloud 负责 “宏观治理”,Dubbo 负责 “微观性能”:
-
SpringCloud 层:承担网关路由(Gateway)、配置中心(Nacos Config)、分布式追踪(Sleuth+SkyWalking)、全局限流(Sentinel)、服务注册发现(Nacos)等 “基础设施” 功能。
-
Dubbo 层:聚焦核心业务服务(如订单、支付、库存)的 RPC 调用,提供高性能通信与细粒度服务治理(如负载均衡、容错)。
-
通信桥接:通过 Nacos 实现服务元数据统一管理,SpringCloud 服务与 Dubbo 服务可双向调用(SpringCloud 通过
@Reference
调用 Dubbo 服务,Dubbo 通过RestTemplate
调用 SpringCloud 服务)。
2.2 整合架构图
2.3 分步整合实战(附完整代码)
前提条件
-
环境准备:Nacos Server 2.2.0(下载地址:https://github.com/alibaba/nacos/releases),启动命令:
sh ``startup.sh`` -m standalone
-
技术版本:Spring Boot 2.7.10,Spring Cloud Alibaba 2021.0.5.0,Dubbo 3.2.0
步骤 1:统一依赖管理(父 POM)
\<parent>\<groupId>org.springframework.boot\</groupId>\<artifactId>spring-boot-starter-parent\</artifactId>\<version>2.7.10\</version>\<relativePath/>\</parent>\<dependencyManagement>\<dependencies>\<!-- Spring Cloud Alibaba 依赖管理 -->\<dependency>\<groupId>com.alibaba.cloud\</groupId>\<artifactId>spring-cloud-alibaba-dependencies\</artifactId>\<version>2021.0.5.0\</version>\<type>pom\</type>\<scope>import\</scope>\</dependency>\<!-- Dubbo 依赖管理 -->\<dependency>\<groupId>org.apache.dubbo\</groupId>\<artifactId>dubbo-dependencies-bom\</artifactId>\<version>3.2.0\</version>\<type>pom\</type>\<scope>import\</scope>\</dependency>\</dependencies>\</dependencyManagement>
步骤 2:开发 Dubbo 核心服务(以订单服务为例)
2.2.1 定义 Dubbo 服务接口(公共模块)
// 公共接口模块:dubbo-apipublic interface OrderService {/\*\*\* 创建订单\* @param orderId 订单ID\* @param userId 用户ID\* @param productIds 商品ID列表\* @return 订单创建结果\*/OrderResult createOrder(String orderId, String userId, List\<String> productIds);}// 订单结果模型@Datapublic class OrderResult implements Serializable {private String orderId;private Boolean success;private String message;}
2.2.2 实现 Dubbo 服务提供者
- 依赖配置(pom.xml)
\<dependencies>\<!-- Spring Boot 基础 -->\<dependency>\<groupId>org.springframework.boot\</groupId>\<artifactId>spring-boot-starter\</artifactId>\</dependency>\<!-- Dubbo + Spring Boot 整合 -->\<dependency>\<groupId>org.apache.dubbo\</groupId>\<artifactId>dubbo-spring-boot-starter\</artifactId>\</dependency>\<!-- Dubbo + Nacos 注册中心 -->\<dependency>\<groupId>org.apache.dubbo\</groupId>\<artifactId>dubbo-registry-nacos\</artifactId>\</dependency>\<!-- 公共接口模块 -->\<dependency>\<groupId>com.example\</groupId>\<artifactId>dubbo-api\</artifactId>\<version>1.0.0\</version>\</dependency>\<!-- Sentinel 整合(容错限流) -->\<dependency>\<groupId>com.alibaba.csp\</groupId>\<artifactId>sentinel-apache-dubbo3-adapter\</artifactId>\<version>1.8.6\</version>\</dependency>\</dependencies>
- 配置文件(application.yml)
server:port: 8081 # 服务端口spring:application:name: dubbo-order-service # 服务名称(Nacos注册用)cloud:nacos:discovery:server-addr: 127.0.0.1:8848 # Nacos地址dubbo:application:name: dubbo-order-serviceprotocol:name: dubbo # 通信协议port: 20881 # Dubbo服务端口registry:address: nacos://127.0.0.1:8848 # 注册中心地址scan:base-packages: com.example.dubbo.service # Dubbo服务扫描路径consumer:check: false # 启动时不检查服务是否存在(避免依赖服务未启动导致报错)provider:filter: sentinel # 集成Sentinel过滤器(实现限流熔断)
- 服务实现类
@DubboService(version = "1.0.0", group = "order-service-group") // Dubbo服务注解public class OrderServiceImpl implements OrderService {// 调用Dubbo库存服务(本地RPC调用)@DubboReference(version = "1.0.0", group = "inventory-service-group")private InventoryService inventoryService;@Overridepublic OrderResult createOrder(String orderId, String userId, List\<String> productIds) {OrderResult result = new OrderResult();result.setOrderId(orderId);try {// 1. 调用库存服务扣减库存(Dubbo RPC调用)InventoryResult inventoryResult = inventoryService.deductStock(productIds, orderId);if (!inventoryResult.isSuccess()) {result.setSuccess(false);result.setMessage("库存不足:" + inventoryResult.getMessage());return result;}// 2. 模拟订单入库逻辑System.out.println("订单创建成功:" + orderId + ",用户:" + userId);result.setSuccess(true);result.setMessage("订单创建成功");} catch (Exception e) {result.setSuccess(false);result.setMessage("订单创建失败:" + e.getMessage());}return result;}}
- 启动类
@SpringBootApplication@EnableDubbo // 开启Dubbo服务自动配置public class DubboOrderServiceApplication {public static void main(String\[] args) {SpringApplication.run(DubboOrderServiceApplication.class, args);}}
步骤 3:开发 SpringCloud 周边服务(以用户服务为例)
2.3.1 服务实现(REST 接口)
- 配置文件(application.yml)
server:port: 8082 # SpringCloud用户服务端口spring:application:name: sc-user-service # 服务名称(Nacos注册用)cloud:nacos:discovery:server-addr: 127.0.0.1:8848 # 接入Nacos注册中心\# 集成Sleuth实现分布式追踪sleuth:sampler:probability: 1.0 # 采样率100%(生产环境可设0.1)\# 配置SkyWalking(需先启动SkyWalking OAP服务)skywalking:agent:service-name: sc-user-serviceoap-server:urls: http://127.0.0.1:12800\# Dubbo客户端配置(调用Dubbo服务)dubbo:application:name: sc-user-service-consumerregistry:address: nacos://127.0.0.1:8848 # 与Dubbo服务共用注册中心consumer:timeout: 3000 # 调用超时时间(避免RPC调用卡顿)retries: 1 # 重试次数(核心服务建议重试1次,非核心0次)
- 服务实现类(调用 Dubbo 订单服务)
@Servicepublic class UserOrderService {// 注入Dubbo订单服务(通过@DubboReference注解)@DubboReference(version = "1.0.0",group = "order-service-group",cluster = "failfast", // 集群容错策略:快速失败(失败后不重试)loadbalance = "leastactive" // 负载均衡:最少活跃调用数(优先分配给压力小的实例))private OrderService dubboOrderService;/\*\*\* 用户创建订单(SpringCloud服务调用Dubbo服务)\* @param userId 用户ID\* @param productIds 商品ID列表\* @return 订单创建结果\*/public OrderResult createUserOrder(String userId, List\<String> productIds) {// 生成唯一订单ID(雪花算法)String orderId = IdUtil.getSnowflake().nextIdStr();try {// 调用Dubbo订单服务创建订单return dubboOrderService.createOrder(orderId, userId, productIds);} catch (DubboException e) {// 捕获Dubbo调用异常(如服务不可用、超时等)log.error("Dubbo order service call failed, userId: {}, orderId: {}", userId, orderId, e);OrderResult failResult = new OrderResult();failResult.setOrderId(orderId);failResult.setSuccess(false);failResult.setMessage("订单创建失败,请稍后重试");return failResult;}}}
- REST 接口控制器
@RestController@RequestMapping("/api/user")public class UserController {@Autowiredprivate UserOrderService userOrderService;/\*\*\* 前端调用接口:用户创建订单\* @param userId 用户ID\* @param productIds 商品ID(多个用逗号分隔,如"prod1,prod2")\* @return 订单结果\*/@PostMapping("/order")public ResponseEntity\<OrderResult> createOrder(@RequestParam String userId,@RequestParam String productIds) {// 解析商品ID列表List\<String> productIdList = Arrays.asList(productIds.split(","));OrderResult result = userOrderService.createUserOrder(userId, productIdList);return ResponseEntity.ok(result);}/\*\*\* 提供给Dubbo服务调用的接口(获取用户等级)\* @param userId 用户ID\* @return 用户等级(如VIP1、VIP2)\*/@GetMapping("/level/{userId}")public String getUserLevel(@PathVariable String userId) {// 模拟数据库查询用户等级(实际项目需对接用户中心)return userId.startsWith("VIP") ? "VIP2" : "普通用户";}}
- 启动类
@SpringBootApplication@EnableDiscoveryClient // 开启SpringCloud服务注册发现@EnableDubbo // 开启Dubbo客户端功能(用于调用Dubbo服务)public class ScUserServiceApplication {public static void main(String\[] args) {SpringApplication.run(ScUserServiceApplication.class, args);}// 配置RestTemplate(用于Dubbo服务调用SpringCloud接口)@Bean@LoadBalanced // 开启负载均衡(调用SpringCloud服务时自动分发请求)public RestTemplate restTemplate() {return new RestTemplate();}}
步骤 4:配置 SpringCloud Gateway(统一网关)
网关作为混合架构的入口,负责路由转发、鉴权、限流等功能,需同时支持 SpringCloud 和 Dubbo 服务的接入。
- 依赖配置(pom.xml)
\<dependencies>\<!-- SpringCloud Gateway -->\<dependency>\<groupId>org.springframework.cloud\</groupId>\<artifactId>spring-cloud-starter-gateway\</artifactId>\</dependency>\<!-- Nacos服务发现(网关需感知所有服务) -->\<dependency>\<groupId>com.alibaba.cloud\</groupId>\<artifactId>spring-cloud-starter-alibaba-nacos-discovery\</artifactId>\</dependency>\<!-- Sentinel网关限流 -->\<dependency>\<groupId>com.alibaba.cloud\</groupId>\<artifactId>spring-cloud-alibaba-sentinel-gateway\</artifactId>\</dependency>\</dependencies>
- 网关配置(application.yml)
server:port: 8080 # 网关端口(对外暴露)spring:application:name: sc-gatewaycloud:nacos:discovery:server-addr: 127.0.0.1:8848gateway:\# 路由规则配置routes:\# 1. 路由至SpringCloud用户服务\- id: route-sc-useruri: lb://sc-user-service # lb=负载均衡,指向SpringCloud服务名predicates:\- Path=/api/user/\*\* # 匹配路径filters:\- StripPrefix=1 # 移除路径前缀(/api/user/order → /user/order)\- name: Sentinel # 限流过滤器args:resource: route-sc-user # 限流资源名limitApp: default # 限制来源(default=所有来源)grade: 1 # 限流维度(1=QPS,0=线程数)count: 100 # QPS阈值(每秒最多100请求)\# 2. 路由至Dubbo订单服务(通过代理层)\- id: route-dubbo-orderuri: lb://dubbo-order-servicepredicates:\- Path=/api/order/\*\*filters:\- StripPrefix=1\- name: Sentinelargs:resource: route-dubbo-ordercount: 200 # Dubbo服务性能更高,阈值设更高sentinel:transport:dashboard: 127.0.0.1:8080 # Sentinel控制台地址
- 启动类
@SpringBootApplication@EnableDiscoveryClientpublic class ScGatewayApplication {public static void main(String\[] args) {SpringApplication.run(ScGatewayApplication.class, args);}}