微服务架构高级应用(二):Spring Cloud Alibaba 企业级技术栈、组件边界与版本规划
微服务架构高级应用(二):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 Cloud Alibaba 企业级技术栈、组件边界与版本规划
-
- 前言
- 一、Spring Boot、Spring Cloud 与 Spring Cloud Alibaba 的关系
- 二、企业级微服务技术栈分层
- 三、Nacos:注册中心与配置中心
- 四、Spring Cloud Gateway:统一入口而不是业务中心
- 五、OpenFeign:远程调用工具,不是可靠性保障
- 六、Spring Cloud LoadBalancer:实例选择与负载均衡
- 七、Sentinel:流量防护而不是简单限流
- 八、Redis:性能组件与分布式协调组件
- 九、RocketMQ:异步协同和最终一致性
- 十、Seata:特定场景下的分布式事务方案
- 十一、Elasticsearch:搜索引擎而不是主业务库
- 十二、可观测组件的职责边界
- 十三、企业项目版本基线规划
- 十四、使用 Maven BOM 统一管理版本
- 十五、企业级 Maven 多模块结构
- 十六、公共模块设计原则
- 十七、环境隔离规划
- 十八、组件选型的六个判断标准
- 十九、常见版本与组件使用误区
- 二十、企业级技术栈实施顺序
- 二十一、技术栈验收清单
- 二十二、总结
- 下一篇预告
前言
在上一篇文章中,我们已经明确:
微服务高级应用的目标,不只是完成服务拆分,而是让系统具备高可用、高并发、可治理和可观测能力。
当项目进入技术落地阶段,团队通常会开始引入以下组件:
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 被用于所有跨服务业务;
- 公共模块依赖越来越多,最终所有服务相互耦合;
- 开发、测试和生产环境配置混在一起;
- 每个服务自行维护依赖版本,升级时出现大量冲突。
因此,微服务技术栈规划必须解决四个问题:
- 各框架之间是什么关系;
- 每个组件负责什么、不负责什么;
- 版本如何统一管理;
- 工程如何分层和组织。
一、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. 网关不适合处理的逻辑
以下逻辑不应放在网关:
- 创建订单;
- 计算商品价格;
- 扣减库存;
- 计算优惠金额;
- 发放积分;
- 处理退款;
- 执行复杂数据库查询;
- 编排大量业务服务。
原因是:
- 网关属于系统公共入口;
- 网关故障会影响所有服务;
- 复杂业务会阻塞网关线程;
- 网关发布频率不应与业务功能绑定;
- 业务逻辑难以独立测试和扩容。
网关的原则应当是:
轻业务、强治理、低延迟、高稳定。
五、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>
这可能破坏整套依赖关系。
确实需要覆盖时,应当:
- 确认依赖树;
- 阅读组件兼容说明;
- 在父工程统一覆盖;
- 记录覆盖原因;
- 补充集成测试;
- 验证运行时行为。
查看依赖树:
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 企业级技术栈不是多个组件的简单组合,而是一套围绕服务治理、流量治理、数据协同、故障隔离、可观测和持续交付建立的工程体系。
本文需要重点记住以下结论:
- Spring Boot 负责单个应用的开发与运行。
- Spring Cloud 提供分布式系统的统一抽象。
- Spring Cloud Alibaba 提供 Nacos、Sentinel、RocketMQ 和 Seata 等生态集成。
- Gateway 是统一入口,不是业务中心。
- OpenFeign 解决远程调用,不自动解决可靠性和一致性。
- Sentinel 需要结合限流、熔断、降级和规则持久化。
- Redis 是性能和协调组件,不应作为唯一永久业务数据库。
- RocketMQ 必须配合幂等、重试、死信、补偿和对账。
- Seata 应根据业务一致性要求选择,不能在所有场景中强行使用。
- Elasticsearch 是搜索视图,不是核心事务数据源。
- SkyWalking、Prometheus 和 ELK 分别解决链路、指标和日志问题。
- 企业项目应统一版本基线,并通过 Maven BOM 管理依赖。
- 技术栈应分阶段建设,避免一次性引入全部组件。
最后,用一句话概括:
企业级微服务技术选型,不是寻找最先进的单个组件,而是建立职责清晰、版本兼容、运行稳定、能够治理和持续演进的完整技术体系。
下一篇预告
下一篇将继续介绍:
《微服务架构高级应用(三):Nacos 注册中心与配置中心企业级设计》
主要内容包括:
- Nacos 注册中心运行机制;
- 服务注册、心跳和健康检查;
- 临时实例与持久实例;
- Namespace、Group、Service 和 Cluster 规划;
- 开发、测试、预发布和生产环境隔离;
- 配置拆分和 Data ID 命名规范;
- 配置动态刷新;
- 敏感配置安全设计;
- 配置灰度、审计和回滚;
- Nacos 集群、数据库和高可用部署;
- Spring Boot、Spring Cloud 和 Spring Cloud Alibaba 接入示例;
- 常见故障与排查方案。
更多推荐




所有评论(0)