用 Spring Cloud Alibaba 构建稳定高效的微服务架构,我在实战中学到了什么

独立开发小站
2025-06-14 18:53
阅读 501

引子:从一次线上事故说起

引子:从一次线上事故说起

去年我在一家做SaaS平台的公司负责后端系统架构。我们当时正在从单体应用向微服务架构转型,系统模块包括用户管理、权限控制、消息推送、支付、订单、会员体系等等。团队对微服务的理解还在起步阶段,Spring Cloud 是我们的首选框架,而随着业务复杂度上升,传统 Spring Cloud 很多组件已经不够用了,比如服务治理和流量管控方面。

有一次在线上压测的过程中,我们遭遇了一个非常严重的雪崩问题。由于一个核心服务出现了响应延迟,导致整个链路上游的服务相继被拖垮,最终影响了整条业务线,甚至导致部分接口长时间无响应。那次事件之后,我意识到我们需要一套更成熟、更适合中国互联网场景下的微服务解决方案。

在技术选型的时候,我们决定尝试 Spring Cloud Alibaba,因为它不仅支持 Nacos 作为服务注册与发现中心,还有 Sentinel 实现熔断降级限流,Seata 处理分布式事务,OSS 做文件上传等等,几乎覆盖了我们所有微服务的核心需求。

这篇文章就来聊聊我们在生产环境中使用 Spring Cloud Alibaba 的真实经验,包括踩过的坑、解决的关键问题以及性能调优的过程。


我们面临的挑战

我们面临的挑战

我们当时的项目背景其实挺典型的:

  • 系统模块拆分明确,但相互之间存在较多依赖
  • 接口并发量逐渐升高(日均10万+ PV)
  • 需要支持灰度发布、流量控制、故障隔离等能力
  • 原有系统依赖的是 Consul + Hystrix 的方案,但 Hystrix 不再维护且不支持实时动态配置更新

最突出的问题包括几个方面:

  1. 服务发现机制不稳定

    • Consul 在高并发下偶发不可达,影响注册/续约
    • 服务实例状态不能及时同步,出现“假死”节点
  2. 没有统一的流量控制工具

    • Hystrix 已不活跃,功能单一,缺乏细粒度限流能力
    • 无法根据 URL 或用户维度做精细化限流
  3. 分布式事务支持缺失

    • 订单系统需要同时修改库存和积分系统,数据一致性难保障
  4. 运维难度大

    • 各个系统的监控指标分散,没有集中式的可观测能力

这促使我们必须寻找一个更加完整且适合企业级生产环境的微服务框架。


技术方案选型及实施

1. 使用 Nacos 替代 Eureka 做服务注册与发现

Nacos 是 Spring Cloud Alibaba 的核心组件之一,除了提供服务注册发现功能外,还内置了配置中心。我们将其部署为集群模式(主从结构),每个微服务通过 SDK 直接连接到 Nacos 服务。

为什么选择 Nacos?

  • 比较 Eureka,其 CP 设计(基于 Raft 协议)更加可靠,保证了数据的一致性
  • 支持健康检查和服务分组,便于隔离不同环境的服务
  • 可视化界面友好,适合开发人员调试

服务注册示例

spring:
  application:
    name: user-service
  cloud:
    nacos:
      discovery:
        server-addr: nacos-cluster.prod:8848

启动时会自动将自身注册进 Nacos,并定期发送心跳保持可用状态。


2. 用 Sentinel 替换 Hystrix,实现真正的熔断限流

Sentinel 是阿里巴巴开源的流量防护中间件,具备以下优势:

  • 支持 RT、QPS、并发数等多种维度限流规则
  • 支持调用链路级别的熔断策略
  • 提供了 Dashboard 控制台,可以可视化解耦设置规则
  • 可以对接 Nacos,实现限流规则热更新

我们的限流实践

我们在核心订单服务中定义了一组限流规则:

sentinel:
  datasource:
    ds1:
      nacos:
        server-addr: nacos.prod:8848
        dataId: order-service-sentinel.json
        groupId: DEFAULT_GROUP
        rule-type: flow

Nacos 中配置如下 JSON 规则:

[
  {
    "resource": "/order/create",
    "limitApp": "default",
    "grade": 1,
    "count": 500,
    "strategy": 0,
    "controlBehavior": 0,
    "clusterMode": false
  }
]

上面的规则表示 /order/create 接口每秒最多只能处理 500 次请求,超过即拒绝。通过 Sentinel Dashboard 还可以看到实时 QPS 和异常率,非常实用。


3. Seata 解决分布式事务问题

订单服务在创建时,需要减库存、增加积分、记录流水等操作,这些涉及多个数据库实例,必须保证一致性。

我们选用了 Seata 的 AT 模式(自动回滚),通过 undo_log 表实现事务快照。Seata Server 部署在 K8s 上,微服务只需要引入 starter 包并开启注解即可。

核心配置:

seata:
  enabled: true
  application-id: order-service
  tx-service-group: my_tx_group
  service:
    vgroup-mapping:
      my_tx_group: default
  config:
    type: nacos
    nacos:
      server-addr: nacos.prod:8848
      group: SEATA_GROUP

在服务中开启全局事务也非常简单:

@GlobalTransactional
public void createOrder() {
    deductStock();
    addPoints();
    saveOrder();
}

如果某一步骤失败,整个事务都会自动回滚,极大降低了分布式事务代码的编写难度。


4. 分布式链路追踪:SkyWalking + Sleuth + Zipkin

为了实现全链路追踪,我们搭建了 Apache SkyWalking 作为后端 APM 系统,并与 Spring Cloud Sleuth、Zipkin 集成。

关键点:

  • 所有微服务引入 Sleuth + Zipkin Starter
  • 请求头带上 traceId,方便排查问题
  • SkyWalking 自动收集 Span 数据,展示拓扑图和慢接口分析

这部分工作对我们后期的监控排障帮助很大。例如当某个下游服务挂掉导致超时时,我们可以通过 SkyWalking 快速定位是哪个具体服务或方法导致的。


踩过的一些坑

1. Nacos 集群脑裂问题

在初期我们将 Nacos 部署为三节点集群,但由于网络波动,其中一个节点频繁失联,出现了短暂的脑裂现象,导致部分服务实例无法正确注册。

解决方案:

  • 将 Nacos 部署在同一机房内部网,避免跨 IDC 延迟问题
  • 配置 nacos.core.cluster.check-period 缩短检查周期,加快恢复速度
  • 启用持久化存储,重启时可快速恢复元数据

2. Sentinel 本地缓存问题

在某些测试环境中,我们发现 Sentinel 规则更新后并没有立刻生效。原因是它默认会缓存规则一段时间。

解决方法:

  • 修改 csp.sentinel.dashboard.server 地址,确保规则源一致
  • 设置 fetchIntervalSecs 降低刷新间隔
  • 生产环境推荐接入 Nacos 动态配置中心,实现实时更新

3. Seata 死锁导致事务卡住

我们曾在高并发下单过程中遇到 Seata 事务卡住的问题,排查后发现是数据库死锁引起事务未正常提交。

优化建议:

  • 对涉及事务的数据表加上合适的索引,减少锁范围
  • 关键路径尽量先更新,避免长事务持有锁时间过久
  • 使用乐观锁或者分段提交方式替代全局事务

效果和收益总结

负载均衡配置-1

经过半年的打磨,我们的整个系统变得更加稳定和高效。以下是主要效果:

指标 改造前 改造后
平均响应时间 120ms 70ms
接口错误率 ~1.2% < 0.3%
故障恢复时间 数十分钟 分钟级别
系统可观测性 比较差 SkyWalking 全链路支持

我们成功支撑了多个大型促销活动,高峰期 QPS 达到 2w+,没有出现重大故障。

更重要的是,我们构建出了一套可扩展、易维护的微服务架构基础,后续新业务模块可以直接复用已有的治理能力。


给读者的经验分享和建议

如果你也在考虑使用 Spring Cloud Alibaba 来构建自己的微服务体系,结合我的经验,下面是一些实实在在的建议:

✅ 建议一:别一开始就搞太复杂的架构

我们一开始就想集成所有的组件,结果反而让系统变得更复杂,排查问题困难。逐步引入,优先用好 Nacos 和 Sentinel,稳住了再上其他组件。

✅ 建议二:一定要做好监控和报警体系建设

微服务一大难点在于“看不见”。无论是 Sentinel 的 Dashboard、还是 SkyWalking,甚至是日志聚合,都非常重要。不要等到出事才发现“没看到数据”。

✅ 建议三:规范你的服务调用方式和 API 定义

微服务太多很容易陷入“不知道谁调谁”的怪圈。建议制定严格的 API 设计规范,使用 OpenAPI / Swagger 统一暴露接口定义。

✅ 建议四:提前规划分布式事务的使用场景

不是所有地方都需要分布式事务。能靠本地事务解决的问题不要引入全局事务,否则可能会引入额外的复杂性。

✅ 建议五:多和运维同学沟通,做好部署设计

K8s + Docker 是现代微服务的标准组合,但要根据实际情况调整资源限制(CPU/Memory)、副本数和探针策略,避免因资源不足或健康检查不合理导致服务异常。


结语:微服务不是银弹,而是能力提升的阶梯

最后想说,微服务本身并不是解决问题的答案,它只是一个工具和架构风格。真正起作用的是你背后的工程能力、协同机制和稳定性建设。

Spring Cloud Alibaba 给我们提供了一个强有力的武器库,在实际使用过程中,我们也不断摸索着如何将这些工具组合起来,打出最佳效果。

如果你刚开始接触这套生态,不妨从小规模实验开始,慢慢理解每个组件的作用。等真正遇到了瓶颈或问题,你会发现这套生态的力量远比想象中强大。

愿你在微服务的路上少走弯路,也希望这篇经验贴能在关键时刻帮到你。


评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝