很多团队上微服务是被一次故障推着走的:一个 Spring Boot 单体应用,所有业务打在一个 JAR 里部署到几台 ECS,平时没事,一到促销流量翻几倍,数据库连接池瞬间耗尽、线程阻塞服务雪崩、全站不可用近一小时。痛定思痛后拆成多个微服务、上阿里云 ACK(容器服务 Kubernetes 版)、引入 Spring Cloud Alibaba 全家桶做治理。改造后单服务 QPS 上限、可用性、故障恢复时间、发布频率、弹性扩容速度、资源利用率都有数量级改善。下面把这条从 0 到 1 的链路拆开讲。
架构全景与技术选型
整体架构是 ACK 托管版集群跑 Spring Cloud Alibaba 微服务。选型清单和理由:
| 层次 | 组件 | 选型 | 理由 |
|---|---|---|---|
| 容器平台 | K8s 集群 | ACK 托管版 | 免 Master 运维,与阿里云生态深度集成 |
| 服务注册 | 注册中心 | MSE Nacos 2.x | 全托管高可用,配置推送性能强 |
| API 网关 | 流量入口 | Spring Cloud Gateway | 响应式非阻塞,与 Sentinel 原生集成 |
| 流量防护 | 限流熔断 | Sentinel | 规则丰富,Nacos 规则持久化 |
| 分布式事务 | 一致性保障 | Seata AT 模式 | 业务侵入最小,自动补偿 |
| 服务调用 | 声明式客户端 | OpenFeign | 与 Sentinel 集成,熔断降级 |
| 链路追踪 | 全链路可观测 | ARMS APM | 免 Agent 注入,K8s 原生支持 |
| 容器编排 | 部署管理 | Helm | 模板化 + 多环境复用 |
| 弹性伸缩 | 自动扩缩 | HPA + CRD | CPU / 自定义指标驱动 |
ACK 集群搭建
托管版 vs 专用版:小团队不想花精力维护 Master 节点,选托管版——Master 由阿里云托管,只关注 Worker 节点,可用性 SLA 99.95%,无 Master 费用,适合 5000 节点以下规模。专用版需自备 3 台 Master ECS、自行保障可用性,适合大规模或金融合规场景。起步用托管版 + 3 个 Worker 节点。
节点池规划:按业务类型分离,避免混部导致资源浪费和互相干扰。核心服务池用计算型(如 8 核 16G)跑订单交易等核心链路;搜索服务池用内存型(如 8 核 64G)跑内存密集的检索;后台任务池用通用型(如 4 核 16G)跑异步消费。搜索池加 NoSchedule 污点,防止别的 Pod 调度上去抢内存。
网络方案:Flannel 是 Overlay(VXLAN)模式,Pod 用虚拟网段;Terway 是阿里云容器网络 CNI,Pod 直接用 VPC IP,网络性能更优、可被 VPC 内其他资源直接访问。对网络性能和 VPC 集成有要求选 Terway。
存储:按场景选 StorageClass——临时缓存用 emptyDir,共享配置用 ConfigMap,有状态数据用云盘(ESSD),需要多 Pod 共享读用 NAS。
Spring Cloud Alibaba 全链路集成
Nacos:注册 + 配置二合一。命名空间按环境隔离(dev/test/prod),Group 按业务域分组(如 TRADE_GROUP),DataId 按服务+用途。服务注册配 spring.cloud.nacos.discovery;配置中心用灰度发布——同一 DataId 配多版本规则,按 IP 或服务实例标签灰度推送,降低配置变更风险。
Gateway:路由 + 限流 + 熔断。路由规则用 application.yml 声明式配置,按 path 路由到对应服务。关键坑:路由 uri 必须写 lb://服务名 而不是 http://,否则请求绕过 Sentinel Filter Chain,限流不生效。
Sentinel:流控 + 熔断 + 热点 + 系统保护。规则走 Nacos 持久化,避免重启丢失。流控按 QPS/线程数,熔断按慢调用比例或异常比例,热点参数限流防止单一热点打垮全局,系统保护按 CPU/Load 兜底。
Seata:分布式事务。AT 模式业务侵入最小,加 @GlobalTransactional 注解即可,自动生成回滚 SQL。坑在全局锁粒度——AT 模式锁粒度是行锁,并发操作同一行会互相等待,高并发下单场景要缩小事务范围(如库存扣减拆成「预扣走 Redis + 确认走数据库」),并调小锁重试次数、缩短重试间隔。
OpenFeign:服务间调用 + 熔断降级。配超时时间(connectTimeout/readTimeout)并与 Sentinel 集成做熔断,给每个 Feign 客户端写 fallback 类,被调服务挂了走降级逻辑而不是报错。
Sleuth + ARMS:链路追踪。Sleuth 采样配置采样率,ARMS 免 Agent 注入——在 Deployment 加一个注解,ARMS 自动注入 Agent 采集链路、JVM、HTTP 指标。
K8s 部署实战
Dockerfile 多阶段构建:阶段一用 maven 镜像构建,阶段二用精简 jre 镜像运行,镜像体积小。安全上用非 root 用户运行。
Helm Chart 模板化:Chart.yaml 定版本,templates/deployment.yaml 写部署模板,values-prod.yaml 写生产环境配置(副本数、资源、镜像 tag)。多环境靠 values 文件切换,不用改模板。
HPA 弹性伸缩:CPU + 自定义指标双驱动。坑是 metrics-server 默认采集间隔 60s 太长,流量突增时扩容延迟 3-5 分钟,新 Pod 起来流量已回落。改成 15s 采集间隔,minReplicas 提到留 1 个缓冲副本,scaleUp 关掉稳定窗口、允许一次翻倍扩容。
滚动更新 + 金丝雀发布:滚动更新配 maxSurge/maxUnavailable 控制节奏。金丝雀用 Argo Rollouts,按权重逐步切流量(如 5%→20%→100%),每阶段自动分析指标决定继续还是回滚。
ConfigMap / Secret 配置管理:非敏感配置走 ConfigMap 或 Nacos,敏感配置(密钥、证书)必须走 Secret 加密,别把数据库密码写进镜像。
可观测性建设
可观测三支柱:指标(ARMS Prometheus + Grafana 看板,看 JVM、HTTP、自定义业务指标)、日志(iLogtail 采集容器日志到 SLS,禁止日志写本地盘)、链路(ARMS APM 全链路追踪,跨服务调用链一眼到底)。三支柱齐了,故障定位从「翻日志猜原因」变成「看链路找瓶颈」。
五个生产踩坑
坑1:Nacos 注册中心雪崩。大促期间 8 个微服务全部下线但进程正常,服务调用报 No available server。根因是 Nacos 1.x 用 HTTP 短连接做心跳,高并发下连接池耗尽导致心跳超时。解决:升级 Nacos 2.x(gRPC 长连接,心跳性能提升约 10 倍)、切 MSE 托管版 3 节点 + SLB、调心跳超时参数(心跳间隔 5s、超时 15s、IP 删除 30s)。
坑2:Seata 全局锁死锁。下单接口偶发超时,链路卡在 lock retry 阶段 20s+。根因是下单和退款两个全局事务同时操作同一商品库存行,行锁互相等待。解决:缩小事务范围把库存扣减拆成预扣走 Redis + 确认走数据库,调全局锁重试次数从 30 降到 10、重试间隔从 10ms 缩到 5ms。
坑3:Gateway 限流不生效。配了 Sentinel 限流但压测时 QPS 远超阈值不限流。根因是路由 uri 写成 http:// 绕过了 Sentinel Filter Chain。解决:改成 lb://服务名,确认引入 spring-cloud-alibaba-sentinel-gateway 专属依赖(不能引普通 sentinel-web,会冲突)。
坑4:HPA 指标延迟导致扩容不及时。流量突增 HPA 延迟 3-5 分钟,新 Pod 起来流量已回落。根因是 metrics-server 采集间隔 60s + Pod 启动 40s。解决:采集间隔改 15s、minReplicas 留缓冲副本、scaleUp 关稳定窗口允许一次翻倍。
坑5:Pod 启动慢导致就绪探针超时。新 Pod 反复重启,Readiness probe failed。根因是就绪探针 initialDelaySeconds 设 30s 但实际启动需 55s(Nacos 配置拉取 10s + Bean 初始化 30s + 数据库连接 15s)。解决:就绪探针缩短初始等待到 10s、检测间隔 5s、允许 60s 启动时间(5s×12);活性探针延迟设长到 90s 避免误杀;非核心 Bean 加 @Lazy 懒加载加速启动。
最佳实践
微服务拆分三条铁律:团队规模不到 5 人不要拆、业务边界不清晰不要拆、没有明确的性能或发布瓶颈不要拆。为拆而拆只会增加运维成本不带来收益。
ACK 部署检查清单:每个容器都设 requests 和 limits(高)、readiness + liveness 都配(高)、日志采集配好不落盘(中)、敏感配置走 Secret 非敏感走 ConfigMap/Nacos(高)、核心服务配 HPA(高)。这几项没做就别上线。
版本兼容:Spring Cloud Alibaba 各组件版本要严格匹配,Spring Boot / Spring Cloud / Nacos / Sentinel / Seata 有兼容矩阵,乱搭配会出各种诡异问题,接入前查官方兼容表。
从单体到微服务不是把一个 JAR 拆成八个就完事,是把「注册、配置、网关、限流、事务、调用、追踪、部署、伸缩、可观测」这一整套治理能力建起来。架构选型之外,踩坑清单和检查清单才是落地时真正省时间的部分。