微服务架构高级应用(二):Spring Cloud Alibaba 企业级技术栈、组件边界与版本规划

文章摘要:

企业级微服务项目不能简单地将 Nacos、Gateway、OpenFeign、Sentinel、Redis 和 RocketMQ 堆叠在一起。组件职责不清、版本不兼容、公共模块过度封装和环境配置混乱,都会让系统在后期维护中付出高昂成本。本文系统梳理 Spring Boot、Spring Cloud 与 Spring Cloud Alibaba 的关系,明确注册配置、网关、远程调用、流量治理、缓存、消息、事务和可观测组件的职责边界,并给出一套适用于企业项目的版本基线、Maven BOM 管理、模块结构与环境规划方案。

推荐标签:

Spring Cloud Alibaba
Spring Cloud
Spring Boot
微服务
Nacos
Sentinel
OpenFeign
Gateway
Java
系统架构

微服务架构高级应用(二):Spring Cloud Alibaba 企业级技术栈、组件边界与版本规划

微服务项目最常见的问题,不是缺少组件,而是组件使用过多、职责重叠、版本混乱和边界不清。

企业级技术选型的核心,不是追求“组件越多越先进”,而是建立一套稳定、兼容、可治理、可持续升级的技术基线。

文章目录


前言

在上一篇文章中,我们已经明确:

微服务高级应用的目标,不只是完成服务拆分,而是让系统具备高可用、高并发、可治理和可观测能力。

当项目进入技术落地阶段,团队通常会开始引入以下组件:

Spring Boot
Spring Cloud
Spring Cloud Alibaba
Nacos
Spring Cloud Gateway
OpenFeign
Sentinel
Redis
RocketMQ
Seata
Elasticsearch
SkyWalking
Prometheus
Docker
Kubernetes

这些组件看起来各自都很重要。

但如果没有统一规划,项目很容易出现以下问题:

  • Spring Boot 与 Spring Cloud 版本不兼容;
  • Spring Cloud 与 Spring Cloud Alibaba 版本不匹配;
  • Nacos 客户端与服务端未经验证;
  • Gateway 中编写大量业务逻辑;
  • OpenFeign 默认重试导致业务重复执行;
  • Sentinel 只接入控制台,却没有真正治理规则;
  • Redis 被当成永久数据库使用;
  • RocketMQ 消息没有幂等和补偿机制;
  • Seata 被用于所有跨服务业务;
  • 公共模块依赖越来越多,最终所有服务相互耦合;
  • 开发、测试和生产环境配置混在一起;
  • 每个服务自行维护依赖版本,升级时出现大量冲突。

因此,微服务技术栈规划必须解决四个问题:

  1. 各框架之间是什么关系;
  2. 每个组件负责什么、不负责什么;
  3. 版本如何统一管理;
  4. 工程如何分层和组织。

一、Spring Boot、Spring Cloud 与 Spring Cloud Alibaba 的关系

1. Spring Boot:单个服务的应用基础

Spring Boot 主要解决单个 Java 应用的开发和运行问题。

它提供:

  • 自动配置;
  • Starter 依赖;
  • 内嵌 Web 容器;
  • 配置管理;
  • Actuator 健康检查;
  • 日志集成;
  • 测试支持;
  • 应用打包与启动。

一个普通 Spring Boot 服务可以独立运行:

@SpringBootApplication
public class OrderServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(
            OrderServiceApplication.class,
            args
        );
    }
}

Spring Boot 本身并不等于微服务。

它可以用于:

  • 单体应用;
  • 模块化单体;
  • 后台管理系统;
  • 微服务中的独立服务;
  • 定时任务服务;
  • API 服务。

因此可以把 Spring Boot 理解为:

每个服务内部的应用开发底座。


2. Spring Cloud:分布式系统能力抽象

Spring Cloud 建立在 Spring Boot 之上,为分布式系统提供通用抽象。

它主要解决:

  • 服务注册与发现;
  • 配置管理;
  • API 网关;
  • 服务间调用;
  • 客户端负载均衡;
  • 熔断降级;
  • 消息驱动;
  • 分布式链路;
  • 云环境适配。

Spring Cloud 并不一定自己实现全部组件,而是提供统一的编程模型和抽象接口。

例如:

DiscoveryClient
LoadBalancer
OpenFeign
Gateway
Config
CircuitBreaker

开发人员可以在相对统一的模型下替换具体实现。

因此可以把 Spring Cloud 理解为:

微服务和分布式系统的能力标准与抽象层。


3. Spring Cloud Alibaba:阿里生态实现与增强

Spring Cloud Alibaba 在 Spring Cloud 体系上,提供适合国内企业项目的组件集成。

常见能力包括:

能力 常见实现
服务注册与发现 Nacos Discovery
配置中心 Nacos Config
流量控制 Sentinel
熔断降级 Sentinel
服务调用 OpenFeign
分布式事务 Seata
消息集成 RocketMQ
负载均衡 Spring Cloud LoadBalancer

三者之间的关系可以表示为:

Spring Boot
    ↓
负责单个应用的启动、配置与运行
    ↓
Spring Cloud
    ↓
提供分布式系统的统一抽象
    ↓
Spring Cloud Alibaba
    ↓
提供 Nacos、Sentinel、RocketMQ、Seata 等生态集成

需要特别注意:

Spring Cloud Alibaba 不是 Spring Cloud 的替代品,而是建立在 Spring Cloud 体系上的扩展实现。


二、企业级微服务技术栈分层

企业级微服务技术栈可以划分为七个层次。

┌────────────────────────────────────────────┐
│                客户端接入层                 │
│ Web / App / 小程序 / 第三方 / IoT          │
└───────────────────┬────────────────────────┘
                    │
┌───────────────────▼────────────────────────┐
│                统一网关层                   │
│ Gateway / 鉴权 / 路由 / 限流 / 灰度        │
└───────────────────┬────────────────────────┘
                    │
┌───────────────────▼────────────────────────┐
│                服务治理层                   │
│ Nacos / OpenFeign / LoadBalancer / Sentinel│
└───────────────────┬────────────────────────┘
                    │
┌───────────────────▼────────────────────────┐
│                业务服务层                   │
│ 用户 / 商品 / 库存 / 订单 / 支付 / 消息     │
└────────────┬──────────────────┬────────────┘
             │                  │
┌────────────▼──────────┐ ┌─────▼────────────┐
│      异步协同层        │ │     数据能力层     │
│ RocketMQ / XXL-JOB    │ │ MySQL / Redis / ES│
│ 状态机 / 补偿 / 对账   │ │ 文件 / 检索 / 分析 │
└────────────┬──────────┘ └─────┬────────────┘
             │                  │
┌────────────▼──────────────────▼────────────┐
│              可观测与交付层                 │
│ SkyWalking / Prometheus / ELK / Docker/K8s│
└────────────────────────────────────────────┘

每一层都应该有明确边界。

最危险的情况不是少一个组件,而是多个组件职责重叠,或者把业务逻辑放到了错误的层次。


三、Nacos:注册中心与配置中心

Nacos 通常承担两类职责:

服务注册与发现
配置集中管理

1. 服务注册与发现

服务启动时向 Nacos 注册:

spring:
  application:
    name: order-service

  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: local
        group: DEFAULT_GROUP

其他服务可以通过服务名称发现订单服务实例。

例如:

@FeignClient(name = "order-service")
public interface OrderFeignClient {

    @GetMapping("/internal/orders/{id}")
    OrderDTO getOrder(@PathVariable("id") Long id);
}

注册中心主要负责:

  • 服务实例注册;
  • 服务实例注销;
  • 健康检查;
  • 服务列表维护;
  • 实例元数据;
  • 集群和分组;
  • 服务变更通知。

注册中心不负责:

  • 用户权限判断;
  • 业务路由判断;
  • 接口幂等;
  • 数据一致性;
  • 消息可靠投递;
  • 业务补偿。

2. 配置中心

配置中心用于集中管理配置:

spring:
  config:
    import:
      - optional:nacos:order-service.yaml
      - optional:nacos:common-redis.yaml
      - optional:nacos:common-monitor.yaml

适合放入配置中心的内容包括:

  • 数据库连接信息;
  • Redis 连接信息;
  • MQ 连接信息;
  • 服务调用超时;
  • 业务开关;
  • 限流参数;
  • 灰度规则;
  • 文件服务地址;
  • 第三方接口地址;
  • 告警阈值。

不建议直接明文保存的内容包括:

  • 数据库密码;
  • Redis 密码;
  • AccessKey;
  • SecretKey;
  • 私钥;
  • 支付密钥;
  • 短信平台密钥。

敏感配置应配合:

配置加密
密钥管理系统
环境变量
Kubernetes Secret
权限控制
变更审计

3. Nacos 不应承担业务数据库职责

不应在 Nacos 中保存:

  • 用户业务数据;
  • 订单状态;
  • 商品库存;
  • 会话明细;
  • 业务流水;
  • 大量动态规则数据。

Nacos 是配置和服务治理组件,不是通用数据存储系统。


四、Spring Cloud Gateway:统一入口而不是业务中心

Spring Cloud Gateway 位于客户端和内部服务之间。

它的核心职责包括:

统一入口
动态路由
身份认证
权限前置校验
流量控制
黑白名单
灰度发布
日志审计
TraceId 注入
跨域处理
统一异常

1. 基础路由示例

spring:
  cloud:
    gateway:
      routes:
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/orders/**
          filters:
            - StripPrefix=1

这里的:

lb://order-service

表示通过服务发现和负载均衡访问订单服务。


2. 网关适合处理的逻辑

网关适合处理:

  • Token 是否存在;
  • Token 是否有效;
  • 请求是否来自允许的 IP;
  • 用户是否具备接口访问权限;
  • 请求是否超过频率限制;
  • 请求应路由到哪个版本;
  • 是否需要注入 TraceId;
  • 是否需要记录访问日志。

3. 网关不适合处理的逻辑

以下逻辑不应放在网关:

  • 创建订单;
  • 计算商品价格;
  • 扣减库存;
  • 计算优惠金额;
  • 发放积分;
  • 处理退款;
  • 执行复杂数据库查询;
  • 编排大量业务服务。

原因是:

  1. 网关属于系统公共入口;
  2. 网关故障会影响所有服务;
  3. 复杂业务会阻塞网关线程;
  4. 网关发布频率不应与业务功能绑定;
  5. 业务逻辑难以独立测试和扩容。

网关的原则应当是:

轻业务、强治理、低延迟、高稳定。


五、OpenFeign:远程调用工具,不是可靠性保障

OpenFeign 可以降低服务间 HTTP 调用的开发成本。

@FeignClient(
    name = "stock-service",
    contextId = "stockFeignClient"
)
public interface StockFeignClient {

    @PostMapping("/internal/stocks/deduct")
    StockDeductResult deduct(
        @RequestBody StockDeductRequest request
    );
}

但 OpenFeign 只解决“如何调用”,并不会自动解决:

  • 调用幂等;
  • 数据一致性;
  • 重复请求;
  • 业务补偿;
  • 分布式事务;
  • 调用链雪崩;
  • 下游容量不足。

1. 所有 Feign 调用必须配置超时

参考配置:

spring:
  cloud:
    openfeign:
      client:
        config:
          default:
            connect-timeout: 1000
            read-timeout: 3000
            logger-level: basic

不同接口应根据实际响应时间制定不同策略。

例如:

接口类型 建议原则
用户基础信息查询 超时较短,可降级
商品详情查询 可缓存,可降级
库存查询 超时较短,结果需谨慎使用
库存扣减 必须幂等,谨慎重试
支付下单 禁止无条件自动重试
文件上传 需要独立超时
报表导出 不应通过长时间同步调用完成

2. 非幂等接口禁止无条件重试

以下请求重复执行可能产生严重后果:

创建订单
扣减库存
执行支付
执行退款
发放优惠券
增加积分
创建工单
发送奖励

因此,不能只依靠“关闭重试”。

服务端仍应设计幂等机制。

常见方法包括:

业务唯一键
请求流水号
幂等记录表
Redis SET NX
数据库唯一索引
状态机条件更新
消息消费记录

例如:

CREATE UNIQUE INDEX uk_order_request_no
ON trade_order(request_no);

即使请求被重复发送,数据库唯一索引也能作为最后一道保护。


3. Feign 接口不能无限扩张

一个业务服务不应暴露大量内部实现接口。

建议将接口区分为:

外部开放接口
内部服务接口
后台管理接口
回调接口

例如:

/api/**          面向客户端
/admin-api/**    面向管理后台
/internal/**     面向内部服务
/callback/**     面向第三方回调

内部接口还应考虑:

  • 网关是否禁止外部访问;
  • 服务身份认证;
  • 内部签名;
  • 调用来源校验;
  • 租户上下文;
  • 用户上下文透传。

六、Spring Cloud LoadBalancer:实例选择与负载均衡

Spring Cloud LoadBalancer 负责从多个服务实例中选择目标实例。

例如订单服务存在三个实例:

10.0.1.11:8080
10.0.1.12:8080
10.0.1.13:8080

负载均衡器根据策略选择其中一个实例。

常见策略包括:

  • 轮询;
  • 随机;
  • 权重;
  • 同集群优先;
  • 同机房优先;
  • 版本匹配;
  • 灰度标签;
  • 基于响应时间;
  • 基于实例负载。

默认轮询并不能满足所有企业场景。

例如灰度发布时,可以通过实例元数据标记版本:

spring:
  cloud:
    nacos:
      discovery:
        metadata:
          version: v2
          region: us-east
          lane: gray

再根据用户、租户或者请求头,将流量路由到指定版本。


七、Sentinel:流量防护而不是简单限流

很多项目接入 Sentinel 后,只在控制台配置一个 QPS 阈值。

这种方式只能算基础使用。

Sentinel 可以承担:

  • QPS 限流;
  • 并发线程数控制;
  • 慢调用比例熔断;
  • 异常比例熔断;
  • 异常数熔断;
  • 热点参数限流;
  • 系统自适应保护;
  • 来源访问控制;
  • 集群流控;
  • 降级兜底。

1. 限流

例如订单查询接口最大允许每秒 500 次请求:

资源:GET:/orders/{id}
阈值类型:QPS
单机阈值:500

超过阈值后,不应继续压向业务服务和数据库。


2. 熔断

假设库存服务最近一段时间响应明显变慢。

熔断器可以暂时阻止新请求进入库存服务,防止上游线程持续堆积。

熔断重点关注:

  • 统计窗口;
  • 最小请求数;
  • 慢调用阈值;
  • 慢调用比例;
  • 异常比例;
  • 熔断时长;
  • 半开恢复策略。

3. 降级

降级必须区分核心业务和非核心业务。

可以降级的场景:

  • 推荐列表;
  • 浏览记录;
  • 用户画像;
  • 非实时统计;
  • 营销展示;
  • 次要消息通知。

不能伪降级的场景:

  • 支付是否成功;
  • 库存是否扣减;
  • 退款是否完成;
  • 订单是否创建;
  • 用户权限是否真实有效。

对于核心交易接口,降级通常应返回明确失败或处理中,而不能返回虚假的成功结果。


4. Sentinel 规则需要持久化

仅保存在客户端内存或控制台中的规则,在应用重启后可能丢失。

生产环境应考虑将规则持久化到:

  • Nacos;
  • 数据库;
  • Apollo;
  • 其他配置中心。

规则还应具备:

版本管理
环境隔离
变更审计
灰度验证
回滚能力

八、Redis:性能组件与分布式协调组件

Redis 常见用途包括:

  • 热点缓存;
  • 用户会话;
  • 验证码;
  • 计数器;
  • 排行榜;
  • 分布式锁;
  • 限流;
  • 在线状态;
  • 短期业务状态;
  • 延迟辅助;
  • 幂等辅助。

Redis 不应被简单理解为:

一个比 MySQL 更快的数据库。


1. Redis 适合保存什么

适合保存:

  • 可重新构建的数据;
  • 有明确过期时间的数据;
  • 高频访问的热点数据;
  • 短期状态数据;
  • 高性能计数数据;
  • 共享会话;
  • 分布式协调信息。

2. Redis 不适合直接承担什么

不适合直接承担:

  • 唯一永久订单数据;
  • 唯一支付流水;
  • 唯一财务记录;
  • 无备份的重要业务数据;
  • 超大对象;
  • 无期限增长的集合;
  • 缺少清理机制的日志数据。

3. 企业级 Redis 设计重点

Key 命名规范
TTL 规划
序列化规范
缓存穿透
缓存击穿
缓存雪崩
热点 Key
大 Key
缓存一致性
分布式锁
主从与集群
容量规划
监控告警
故障恢复

Redis 的详细方案将在本系列后续专题中展开。


九、RocketMQ:异步协同和最终一致性

RocketMQ 主要用于:

  • 异步解耦;
  • 流量削峰;
  • 事件驱动;
  • 延迟消息;
  • 顺序消息;
  • 事务消息;
  • 最终一致性;
  • 跨系统通知。

例如支付成功后发布事件:

Topic:trade-payment-event
Tag:PAYMENT_SUCCESS
Key:paymentNo

消费者包括:

订单服务
库存服务
积分服务
消息服务
统计服务

1. 消息不是远程方法调用的替代语法

发送消息以后,生产者通常无法立即获得所有消费者的处理结果。

因此,消息适合:

  • 不要求立即返回结果;
  • 可以接受最终一致;
  • 可以异步处理;
  • 可以失败重试;
  • 消费者之间需要解耦。

消息不适合直接替代所有同步查询。

例如查询商品当前价格,一般仍需要同步调用或缓存查询。


2. 消息系统必须具备幂等设计

RocketMQ 通常保证至少一次投递。

这意味着消费者必须接受消息重复到达。

消费幂等可以采用:

消息唯一键
业务唯一键
消费记录表
Redis 去重
数据库唯一索引
状态机条件更新

例如:

UPDATE trade_order
SET status = 'PAID',
    paid_time = NOW()
WHERE order_no = ?
  AND status = 'WAIT_PAY';

只有订单当前状态为 WAIT_PAY 时才允许更新。

即使支付成功消息重复到达,也不会重复修改订单。


3. 消息失败必须有补偿闭环

完整消息治理至少包括:

生产结果确认
Broker 存储确认
消费结果确认
失败重试
死信队列
人工处置
定时补偿
业务对账
监控告警

只发送消息而没有补偿机制,并不能真正保证业务可靠性。


十、Seata:特定场景下的分布式事务方案

Seata 可以用于解决部分跨服务事务问题。

但它不应该成为所有跨服务业务的默认答案。

常见模式包括:

模式 特点
AT 对业务代码侵入较低,依赖数据库事务
TCC 业务明确实现 Try、Confirm、Cancel
Saga 适合长事务和多步骤业务
XA 强一致,但资源和性能成本较高

1. 适合使用 Seata 的场景

  • 参与方数量有限;
  • 数据库类型和事务模型可控;
  • 事务执行时间较短;
  • 业务需要较高一致性;
  • 团队具备运维和故障处理能力;
  • 已完成容量和性能验证。

2. 不适合盲目使用 Seata 的场景

  • 长时间业务流程;
  • 包含大量第三方系统;
  • 包含人工审核;
  • 跨越多个异构数据源;
  • 高并发核心交易;
  • 可以接受最终一致性的业务;
  • 无法稳定回滚的外部调用。

很多企业项目更适合:

本地事务
+ 可靠消息
+ 消费幂等
+ 业务状态机
+ 定时补偿
+ 对账机制

十一、Elasticsearch:搜索引擎而不是主业务库

Elasticsearch 适合:

  • 全文检索;
  • 商品搜索;
  • 多条件过滤;
  • 高亮;
  • 搜索建议;
  • 聚合统计;
  • 日志检索;
  • 地理位置搜索。

Elasticsearch 不适合作为核心事务数据的唯一真实来源。

推荐架构:

MySQL
  ↓
业务事件 / CDC
  ↓
Elasticsearch
  ↓
搜索服务

原则是:

MySQL 负责真实业务数据
Elasticsearch 负责搜索视图

当索引数据异常时,应当能够从真实数据源重新构建。


十二、可观测组件的职责边界

1. SkyWalking

主要负责:

  • 分布式链路追踪;
  • 服务拓扑;
  • 接口耗时;
  • 慢调用分析;
  • 数据库调用分析;
  • Trace 和 Span;
  • 服务依赖分析。

2. Prometheus

主要负责:

  • 指标采集;
  • 时序数据存储;
  • 服务指标;
  • JVM 指标;
  • 中间件指标;
  • 基础设施指标;
  • 告警规则计算。

3. Grafana

主要负责:

  • 指标可视化;
  • 仪表盘;
  • 趋势分析;
  • 业务大盘;
  • 运维大盘。

4. ELK

主要负责:

Elasticsearch:日志存储与检索
Logstash:日志处理
Kibana:日志查询和展示

在容器环境中,也可以使用 Filebeat、Fluent Bit 等采集日志。


5. 三者不能相互完全替代

SkyWalking:请求经过哪里
Prometheus:系统运行得怎么样
ELK:具体发生了什么

企业级可观测体系通常需要将三者结合使用。


十三、企业项目版本基线规划

版本规划的第一原则是:

不追求单个组件最新,而追求整套技术栈兼容、稳定、可验证。

以下可以作为传统 Java 微服务项目的一套固定基线示例。

该表用于说明版本统一方法,不代表所有项目都必须使用完全相同的版本,也不代表当前最新版本。

组件 项目基线示例
JDK 11
Spring Boot 2.7.18
Spring Cloud 2021.0.9
Spring Cloud Alibaba 2021.0.6.1
Nacos Server 2.3.0
MyBatis-Plus 3.5.3.1
MySQL Connector/J 8.0.33
MySQL Server 8.0.x
Redis 7.2.x
RocketMQ 5.x
Elasticsearch 7.17.x
Maven 3.8.x 及以上

这套基线适合:

  • 已有 Spring Boot 2.x 项目;
  • JDK 11 环境;
  • 需要控制升级风险;
  • 存在较多旧组件依赖;
  • 尚未完成 Jakarta 命名空间迁移的系统。

1. 为什么版本必须成套选择

不能单独决定:

“我要使用 Spring Boot 2.7.18”

还需要同步确认:

Spring Cloud 版本
Spring Cloud Alibaba 版本
Nacos 客户端版本
Sentinel 版本
OpenFeign 版本
LoadBalancer 版本
第三方 Starter 兼容性

否则可能出现:

  • 类找不到;
  • 方法签名不一致;
  • 自动配置失效;
  • Bean 重复;
  • 配置项不生效;
  • 启动时依赖冲突;
  • 运行时 NoSuchMethodError
  • Jakarta 与 Javax 包冲突。

2. 版本升级不应跨越过大

不建议在一次迭代中同时完成:

JDK 11 → JDK 21
Spring Boot 2 → Spring Boot 3
Spring Cloud 2021 → 新一代版本
Elasticsearch 7 → Elasticsearch 8
MyBatis-Plus 大版本升级
认证框架替换
部署平台迁移

这种升级范围过大,问题出现后很难定位。

更合理的升级方式是:

第一步:依赖收敛和测试补齐
第二步:JDK 升级验证
第三步:Spring Boot 主版本升级
第四步:Spring Cloud 体系升级
第五步:中间件客户端升级
第六步:中间件服务端升级
第七步:性能和稳定性验证

十四、使用 Maven BOM 统一管理版本

企业项目不应在每个子模块中单独声明 Spring 组件版本。

推荐使用 Maven BOM 统一管理。

1. 父工程示例

<properties>
    <java.version>11</java.version>

    <spring-boot.version>2.7.18</spring-boot.version>
    <spring-cloud.version>2021.0.9</spring-cloud.version>
    <spring-cloud-alibaba.version>
        2021.0.6.1
    </spring-cloud-alibaba.version>

    <mybatis-plus.version>3.5.3.1</mybatis-plus.version>
    <mysql.version>8.0.33</mysql.version>
</properties>

依赖管理:

<dependencyManagement>
    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>
                spring-cloud-alibaba-dependencies
            </artifactId>
            <version>
                ${spring-cloud-alibaba.version}
            </version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-bom</artifactId>
            <version>${mybatis-plus.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

    </dependencies>
</dependencyManagement>

子模块只声明依赖,不重复声明版本:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>
        spring-cloud-starter-alibaba-nacos-discovery
    </artifactId>
</dependency>

2. BOM 的价值

使用 BOM 可以:

  • 统一依赖版本;
  • 减少版本冲突;
  • 降低升级成本;
  • 避免模块自行覆盖版本;
  • 便于安全漏洞统一修复;
  • 便于生成软件物料清单;
  • 提高构建可重复性。

3. 不要随意覆盖 BOM 管理的版本

部分项目为了修复一个问题,直接在子模块中加入:

<version>其他版本</version>

这可能破坏整套依赖关系。

确实需要覆盖时,应当:

  1. 确认依赖树;
  2. 阅读组件兼容说明;
  3. 在父工程统一覆盖;
  4. 记录覆盖原因;
  5. 补充集成测试;
  6. 验证运行时行为。

查看依赖树:

mvn dependency:tree

查看指定依赖:

mvn dependency:tree \
  -Dincludes=org.springframework:*

十五、企业级 Maven 多模块结构

推荐将项目分为:

microservice-platform
├── platform-bom
├── platform-common
├── platform-gateway
├── platform-auth
├── services
├── infrastructure
├── deploy
└── docs

进一步展开:

microservice-platform
├── pom.xml
│
├── platform-bom
│   └── pom.xml
│
├── platform-common
│   ├── common-core
│   ├── common-web
│   ├── common-security
│   ├── common-feign
│   ├── common-redis
│   ├── common-mq
│   ├── common-log
│   ├── common-trace
│   └── common-test
│
├── platform-gateway
├── platform-auth
│
├── services
│   ├── user-service
│   ├── product-service
│   ├── catalog-service
│   ├── stock-service
│   ├── order-service
│   ├── payment-service
│   ├── marketing-service
│   ├── message-service
│   ├── file-service
│   └── search-service
│
├── infrastructure
│   ├── nacos
│   ├── redis
│   ├── rocketmq
│   ├── mysql
│   ├── elasticsearch
│   ├── skywalking
│   ├── prometheus
│   └── grafana
│
├── deploy
│   ├── docker
│   ├── docker-compose
│   ├── kubernetes
│   └── helm
│
└── docs
    ├── architecture
    ├── api
    ├── database
    ├── deployment
    └── operations

十六、公共模块设计原则

公共模块非常容易发展成新的“单体核心”。

错误做法是:

common 模块依赖所有业务服务
所有业务对象都放进 common
所有 Mapper 都放进 common
所有服务都依赖一个超大 common

这样会导致:

  • 所有服务一起升级;
  • 业务边界被打破;
  • 编译依赖复杂;
  • 循环依赖;
  • 发布耦合;
  • 公共模块变成超级模块。

公共模块只应放置真正稳定、跨业务复用的能力。

适合放入公共模块:

统一响应结构
基础异常
公共枚举
日志规范
TraceId 处理
Web 基础配置
Feign 基础配置
Redis 序列化
安全上下文
测试基础工具

不适合放入公共模块:

订单业务对象
商品业务规则
库存扣减逻辑
支付状态机
营销优惠算法
具体业务 Mapper
跨服务业务编排

判断标准是:

删除某个业务服务后,这段公共代码是否仍然有独立价值。


十七、环境隔离规划

企业项目至少应区分:

local
dev
test
staging
prod

1. Nacos Namespace 规划

可以按照环境规划:

local
dev
test
staging
prod

每个环境使用独立 Namespace。

这样可以避免:

  • 测试服务调用生产服务;
  • 开发配置污染生产;
  • 测试限流规则影响生产;
  • 灰度配置跨环境传播;
  • 测试账号连接生产数据库。

2. Group 规划

Group 可以按系统或业务域划分:

DEFAULT_GROUP
TRADE_GROUP
USER_GROUP
INFRA_GROUP
MONITOR_GROUP

不建议将 Group 设计得过度复杂。

环境优先使用 Namespace 隔离,Group 用于业务或配置类别划分。


3. Data ID 规划

推荐格式:

${application-name}-${profile}.${file-extension}

例如:

order-service-local.yaml
order-service-dev.yaml
order-service-test.yaml
order-service-prod.yaml

公共配置可以使用:

common-datasource.yaml
common-redis.yaml
common-rocketmq.yaml
common-monitor.yaml
common-security.yaml

4. 配置优先级必须明确

常见配置来源包括:

代码默认值
application.yaml
application-{profile}.yaml
Nacos 公共配置
Nacos 应用配置
环境变量
启动参数
Kubernetes ConfigMap
Kubernetes Secret

团队必须明确:

  • 哪一层优先级最高;
  • 哪些配置允许覆盖;
  • 哪些配置禁止动态修改;
  • 哪些配置修改后需要重启;
  • 哪些配置需要审批;
  • 哪些配置属于敏感信息。

十八、组件选型的六个判断标准

选择组件时,不应只问“这个组件是否流行”。

至少应评估以下六个方面。

1. 是否真正匹配业务问题

例如:

  • 数据量不大时,不一定需要 Elasticsearch;
  • 没有异步场景时,不必过早引入 RocketMQ;
  • 单体应用阶段,不一定需要完整微服务治理;
  • 简单事务不一定需要 Seata;
  • 小规模部署不一定立即需要 Kubernetes。

2. 团队是否具备维护能力

引入一个组件,意味着团队需要掌握:

部署
配置
监控
备份
升级
扩容
故障恢复
安全加固
应急处理

只有开发人员会调用 API,但没有人能处理集群故障,这个组件就不能算真正落地。


3. 是否具备稳定的社区与生态

需要考虑:

  • 社区活跃度;
  • 文档完整性;
  • 安全修复;
  • 客户端支持;
  • 运维工具;
  • 监控能力;
  • 企业案例;
  • 长期维护能力。

4. 是否能够监控和告警

一个不能被监控的组件,很难用于生产环境。

至少要能监控:

  • 可用性;
  • 延迟;
  • 错误率;
  • 容量;
  • 连接数;
  • 队列积压;
  • 资源使用;
  • 主从或集群状态。

5. 是否具备故障恢复能力

需要提前明确:

  • 单节点故障怎么办;
  • 集群不可用怎么办;
  • 数据损坏怎么办;
  • 配置误操作怎么办;
  • 版本升级失败怎么办;
  • 客户端不兼容怎么办;
  • 如何回滚;
  • 恢复需要多长时间。

6. 引入后的总成本是多少

组件成本不仅包括服务器成本。

还包括:

学习成本
开发成本
测试成本
运维成本
监控成本
升级成本
故障成本
安全成本
人员成本

架构设计不是组件数量竞赛。


十九、常见版本与组件使用误区

误区一:所有组件都选择最新版

最新版可能意味着:

  • 文档不足;
  • 第三方组件尚未兼容;
  • 已有问题没有充分暴露;
  • 团队缺少实践;
  • 迁移成本高;
  • 回滚困难。

企业项目更关注经过验证的稳定组合。


误区二:每个服务自己选择依赖版本

这样最终会出现:

订单服务使用一套版本
商品服务使用另一套版本
网关又使用第三套版本

短期看开发灵活,长期会导致:

  • 问题难复现;
  • 公共组件无法统一;
  • 安全漏洞难统一修复;
  • 升级成本极高;
  • 运维行为不一致。

误区三:公共模块引入全部 Starter

例如在 common-core 中引入:

Web
Redis
RocketMQ
Nacos
MyBatis
Security
Elasticsearch

结果是所有服务都被动引入大量无用依赖。

公共模块应保持职责单一。


误区四:Nacos 同时充当配置、数据和规则数据库

业务规则如果具备以下特征:

  • 数据量大;
  • 高频写入;
  • 需要复杂查询;
  • 需要事务;
  • 需要历史版本;
  • 需要业务审计;

通常应使用数据库和专门的管理模块,而不是直接存入 Nacos。


误区五:Gateway 承担所有系统逻辑

网关一旦成为业务中心,会导致:

  • 单点复杂度过高;
  • 所有业务发布都需要更新网关;
  • 网关吞吐下降;
  • 故障影响全系统;
  • 业务无法独立扩容。

误区六:引入 MQ 就认为实现了最终一致性

最终一致性还需要:

消息可靠发送
消费幂等
业务状态机
失败重试
死信处理
定时补偿
数据对账
人工修复
监控告警

缺少其中任何关键环节,都可能出现数据不一致。


二十、企业级技术栈实施顺序

建议按照四个阶段推进。

第一阶段:统一技术基线

完成:

JDK 版本统一
Spring Boot 版本统一
Spring Cloud 版本统一
Spring Cloud Alibaba 版本统一
Maven BOM
编码规范
接口规范
异常规范
日志规范
模块规范

第二阶段:建设核心治理能力

引入:

Nacos
Gateway
OpenFeign
LoadBalancer
Sentinel
Redis

解决:

  • 服务发现;
  • 配置管理;
  • 统一入口;
  • 远程调用;
  • 超时控制;
  • 熔断降级;
  • 基础缓存。

第三阶段:建设异步和数据能力

引入:

RocketMQ
XXL-JOB
Elasticsearch
分布式事务
状态机
补偿任务

解决:

  • 异步解耦;
  • 流量削峰;
  • 最终一致性;
  • 复杂检索;
  • 超时任务;
  • 数据补偿。

第四阶段:建设生产治理体系

引入:

SkyWalking
Prometheus
Grafana
ELK
Docker
Kubernetes
CI/CD

解决:

  • 链路追踪;
  • 指标监控;
  • 日志检索;
  • 自动告警;
  • 自动构建;
  • 灰度发布;
  • 快速回滚;
  • 弹性扩容。

二十一、技术栈验收清单

项目技术栈完成建设后,可以按照以下清单验收。

版本管理

  • 是否统一 JDK 版本;
  • 是否统一 Spring Boot 版本;
  • 是否统一 Spring Cloud 版本;
  • 是否统一 Spring Cloud Alibaba 版本;
  • 是否使用 BOM;
  • 是否禁止子模块随意覆盖版本;
  • 是否能够输出完整依赖树。

Nacos

  • 是否完成环境隔离;
  • 是否完成 Namespace 规划;
  • 是否完成 Group 规划;
  • 是否完成配置权限控制;
  • 是否具备配置审计;
  • 是否具备配置回滚;
  • 是否配置健康检查。

Gateway

  • 是否统一路由;
  • 是否统一认证;
  • 是否统一异常;
  • 是否统一 TraceId;
  • 是否配置限流;
  • 是否支持灰度;
  • 是否避免复杂业务逻辑。

OpenFeign

  • 是否统一超时;
  • 是否区分查询和写操作;
  • 非幂等接口是否禁止无条件重试;
  • 是否透传 TraceId;
  • 是否透传用户和租户上下文;
  • 是否配置异常转换。

Sentinel

  • 是否配置核心资源;
  • 是否区分限流、熔断和降级;
  • 是否设计兜底结果;
  • 是否完成规则持久化;
  • 是否具备规则审计和回滚。

Redis

  • 是否统一 Key 规范;
  • 是否设置 TTL;
  • 是否治理穿透、击穿和雪崩;
  • 是否监控热点 Key 和大 Key;
  • 是否完成高可用规划;
  • 是否具备容量和故障预案。

RocketMQ

  • 是否统一 Topic 和 Tag 规范;
  • 是否设置业务 Key;
  • 是否完成消费幂等;
  • 是否完成失败重试;
  • 是否处理死信消息;
  • 是否配置补偿和对账;
  • 是否监控消息堆积。

可观测

  • 是否统一日志格式;
  • 是否接入 TraceId;
  • 是否采集 JVM 指标;
  • 是否采集中间件指标;
  • 是否配置告警等级;
  • 是否能够从告警定位到日志和链路。

二十二、总结

Spring Cloud Alibaba 企业级技术栈不是多个组件的简单组合,而是一套围绕服务治理、流量治理、数据协同、故障隔离、可观测和持续交付建立的工程体系。

本文需要重点记住以下结论:

  1. Spring Boot 负责单个应用的开发与运行。
  2. Spring Cloud 提供分布式系统的统一抽象。
  3. Spring Cloud Alibaba 提供 Nacos、Sentinel、RocketMQ 和 Seata 等生态集成。
  4. Gateway 是统一入口,不是业务中心。
  5. OpenFeign 解决远程调用,不自动解决可靠性和一致性。
  6. Sentinel 需要结合限流、熔断、降级和规则持久化。
  7. Redis 是性能和协调组件,不应作为唯一永久业务数据库。
  8. RocketMQ 必须配合幂等、重试、死信、补偿和对账。
  9. Seata 应根据业务一致性要求选择,不能在所有场景中强行使用。
  10. Elasticsearch 是搜索视图,不是核心事务数据源。
  11. SkyWalking、Prometheus 和 ELK 分别解决链路、指标和日志问题。
  12. 企业项目应统一版本基线,并通过 Maven BOM 管理依赖。
  13. 技术栈应分阶段建设,避免一次性引入全部组件。

最后,用一句话概括:

企业级微服务技术选型,不是寻找最先进的单个组件,而是建立职责清晰、版本兼容、运行稳定、能够治理和持续演进的完整技术体系。


下一篇预告

下一篇将继续介绍:

《微服务架构高级应用(三):Nacos 注册中心与配置中心企业级设计》

主要内容包括:

  • Nacos 注册中心运行机制;
  • 服务注册、心跳和健康检查;
  • 临时实例与持久实例;
  • Namespace、Group、Service 和 Cluster 规划;
  • 开发、测试、预发布和生产环境隔离;
  • 配置拆分和 Data ID 命名规范;
  • 配置动态刷新;
  • 敏感配置安全设计;
  • 配置灰度、审计和回滚;
  • Nacos 集群、数据库和高可用部署;
  • Spring Boot、Spring Cloud 和 Spring Cloud Alibaba 接入示例;
  • 常见故障与排查方案。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐