在生产实践中探索 Spring Cloud Alibaba 的力量:一次从单体到微服务的蜕变之路

创新-孙娟-工程师
2025-06-17 09:02
阅读 777

引言:为什么我会选择 Spring Cloud Alibaba?

引言:为什么我会选择 Spring Cloud Alibaba?

2021 年,我参与了一个企业级电商中台系统的重构项目。项目最初的版本是一个单体架构,采用的是传统的 Spring MVC + MyBatis 组合,随着用户量增长和功能模块不断叠加,系统逐渐变得臃肿、部署困难、响应变慢、扩展性差等问题频频暴露出来。

团队在调研后决定进行微服务化改造,我们考虑过使用 Spring Cloud Netflix(如 Eureka、Zuul、Ribbon 等),但由于当时 Netflix 官方宣布对部分组件进入维护模式(不再积极更新),加上国内生态和社区对阿里系技术的支持越发成熟,我们最终选择了 Spring Cloud Alibaba(SCA) 作为本次微服务架构的落地框架。

这篇文章将结合我在该项目中的实践经验,分享我们在使用 SCA 遇到的挑战、踩过的坑以及收获的经验。希望能为同样走在微服务实践路上的你提供一些有价值的参考。


问题描述:微服务化转型中的“阵痛期”

问题描述:微服务化转型中的“阵痛期”

微服务架构示意图-2

1. 单体应用的瓶颈日益明显

  • 启动时间长:每次打包部署都要等十几分钟,严重影响交付效率;
  • 功能耦合严重:修改一个订单模块可能引发支付模块出错;
  • 无法独立伸缩:高并发时所有模块一起扛压,资源浪费严重;
  • 技术栈僵化:难以引入新语言或新技术做实验。

2. 微服务带来的新挑战

  • 服务如何注册发现?怎么做到就近访问?
  • 如何统一鉴权和接口限流?
  • 多个数据库之间如何保证一致性?
  • 调用链监控怎么做?
  • 日志集中收集和分析怎么做?

这些问题听起来都很常见,但在真实生产环境中去解决它们,并不是查几个文档就能搞定的。


解决方案:Spring Cloud Alibaba 架构选型与落地

微服务架构示意图-1

解决方案:Spring Cloud Alibaba 架构选型与落地

我们的整体目标是:

实现服务可拆分、可独立部署、可弹性扩缩容,同时保持系统的稳定性和可观测性。

基于这一目标,我们搭建了如下微服务架构图:

+------------------+        +--------------------+
|      Gateway     | <----> |   Nacos Server     |
+--------+---------+        +----------+---------+
         |                            |
         v                            |
+--------+---------+                 |
|    Auth Server   |<-----------------+
+------------------+
         |
         v
+--------+---------+       +---------------------+
|   Order Service  |<----->|    Sentinel Server    |
+--------+---------+       +----------+----------+
         |
         v
+--------+---------+        +----------------------+
|  Payment Service |<-----> |    Seata Server       |
+------------------+        +-----------+----------+
                                          |
                                          v
                               +-----------------------+
                               |  MySQL Cluster + Redis |
                               +-----------------------+

以下是我们采用的核心组件及其职责说明:

技术组件 使用场景与作用
Nacos 服务注册发现 + 分布式配置管理
Sentinel 接口限流降级,保障系统稳定性
Seata 全局事务管理,用于跨库操作的一致性保障
Gateway + Auth 前端请求统一入口,处理身份认证与权限控制
SkyWalking/Logback 链路追踪、日志采集与集中存储

代码实践:关键模块实现示例

代码实践:关键模块实现示例

1. 服务注册发现 —— Nacos

Nacos 是我们整个服务治理的中枢。下面是在 OrderService 中集成 Nacos Client 的核心步骤。

pom.xml 添加依赖

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

application.yml 配置

server:
  port: 8081

spring:
  application:
    name: order-service
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.0.10:8848 # Nacos 服务地址

主类添加 @EnableDiscoveryClient

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

启动后,服务会自动注册到 Nacos 控制台,便于其他服务发现调用。


2. 接口限流降级 —— Sentinel

当订单服务被大量恶意刷单攻击时,我们采用了 Sentinel 进行流量控制与异常熔断。

pom.xml 添加依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2021.0.4.0</version>
</dependency>

application.yml 配置

spring:
  cloud:
    sentinel:
      transport:
        dashboard: 192.168.0.20:8080  # Sentinel 控制台地址

然后我们在 Controller 上使用注解定义限流规则:

@GetMapping("/order/{id}")
@SentinelResource(value = "getOrderById", fallback = "fallbackGetOrder")
public Order getOrder(@PathVariable String id) {
    return orderService.getOrderById(id);
}

public Order fallbackGetOrder(String id, Throwable ex) {
    log.warn("触发限流降级");
    return new Order("降级订单");
}

通过 Sentinel Dashboard 还可以动态调整 QPS 限制、熔断策略等参数。


3. 全局事务管理 —— Seata

当订单下单涉及库存扣除和余额扣减两个操作时,我们采用了 Seata 实现分布式事务。

数据表加全局事务字段

ALTER TABLE orders ADD COLUMN xid VARCHAR(100);
ALTER TABLE inventory ADD COLUMN xid VARCHAR(100);

pom.xml 加入 Seata 依赖

<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-spring-boot-starter</artifactId>
    <version>1.5.2</version>
</dependency>

application.yml 配置

seata:
  enabled: true
  application-id: ${spring.application.name}
  tx-service-group: my_tx_group
  service:
    vgroup-mapping:
      my_tx_group: default
    grouplist:
      default: 192.168.0.30:8091

接口中开启全局事务

@PostMapping("/placeOrder")
@Transactional
@GlobalTransactional
public Response placeOrder(@RequestBody OrderDTO dto) {
    inventoryService.decreaseStock(dto.getItemId(), dto.getCount());
    paymentService.chargeUser(dto.getUserId(), dto.getTotalPrice());
    return Response.success();
}

如果某一步失败,Seata 会自动进行回滚,有效防止数据不一致的问题。


踩坑经验:那些深夜加班的瞬间

1. Nacos 集群部署踩坑

最初我们只部署了一个 Nacos 节点,结果上线后遇到节点宕机,导致整个服务注册中心瘫痪。后来我们按照官方推荐,在三台机器上做了集群部署,并配合 MySQL 存储持久化数据,避免服务元信息丢失。

建议:
生产环境务必使用至少三个节点组成 Nacos 集群,并关闭嵌入式 DB,使用外部 MySQL 保存服务注册信息。


2. Sentinel 控制台无法连接

在测试环境中,由于网络限制(防火墙),微服务无法连接 Sentinel Dashboard,导致限流策略无法生效。

解决方案:

  • 确认防火墙是否开放了 8719 端口;
  • 查看微服务是否正确配置了 Sentinel 地址;
  • 如果是容器部署,需确认 host 网络是否打通;

3. Seata 分布式事务性能问题

我们在一次压力测试中发现,在每秒并发超过 100 次时,Seata 出现明显的延迟。

排查发现是因为 UndoLog 表没有建立索引,导致 SQL 查询效率低。

优化方法:

为 undo_log 表增加合适的索引:

CREATE INDEX idx_xid ON undo_log(xid);

同时合理设置线程池大小和事务超时时间,提升整体吞吐能力。


4. Gateway 动态路由配置更新延迟

我们使用了 Nacos 作为 Gateway 的动态配置中心,但在初期经常出现配置更新后,路由未生效的情况。

原因分析:
默认情况下,Gateway 刷新机制不够及时,需要手动触发。

改进方式: 启用 Spring Cloud 的自动刷新功能,监听 Nacos 中指定 Data ID 的变化:

spring:
  cloud:
    gateway:
      routes:
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/order/**

并通过以下方式实现实时刷新:

@Component
@RefreshScope
public class RouteLocatorConfig {}

效果总结:从单体到微服务后的转变

经过近半年的迭代与运维,我们的中台系统发生了显著的变化:

  • 部署效率提高:单个服务启动时间从 10+ 分钟缩短到 30 秒内;
  • 故障隔离增强:一个服务异常不会影响整个系统;
  • 弹性扩展可行:可以根据不同业务高峰期灵活扩容订单或支付服务;
  • 运维监控清晰:通过 Sentinel、SkyWalking 和 ELK 实现全链路监控和日志追溯;
  • 开发协作顺畅:不同模块由不同团队负责,降低沟通成本。

更重要的是,业务同学开始感受到系统响应速度的提升,用户体验明显改善。


经验分享:给正在尝试 SCA 的你几点建议

✅ 1. 别急着全量上微服务

微服务不是万能药,先从核心模块拆起,逐步推进,避免因拆分不当造成更大的耦合。

✅ 2. 基础设施先行

微服务意味着更多服务、更多依赖、更复杂的网络拓扑。一定要提前准备好基础设施:

  • 注册中心(Nacos)
  • 配置中心(Nacos)
  • 限流熔断(Sentinel)
  • 分布式事务(Seata)
  • 监控系统(SkyWalking / Prometheus)
  • 日志平台(ELK)

这些都搭好了,才能真正发挥微服务的价值。

✅ 3. 多用社区资源,多读官方文档

Spring Cloud Alibaba 社区活跃,官方文档和 issue 区域都有很多实战经验可借鉴。别怕提问,也别怕踩坑,每一次解决问题都是积累。

✅ 4. 做好灰度发布准备

微服务上线初期风险较大,建议结合网关实现灰度发布,比如根据 User-Agent 或 header 参数决定转发到哪个服务实例。

✅ 5. 坚持持续集成/交付(CI/CD)

每个微服务都应该有自动化构建和部署流程,减少人为干预,提升部署效率和质量。


尾声:一段旅程的终点也是另一段的开始

写到这里,不禁感慨。三年前刚接触 SCA 时,我也曾对着文档迷茫、对着错误日志焦头烂额。但正是那一段段深夜调试、一次次线上排障的经历,让我逐步成长为一名更加成熟的后端架构师。

现在再回头看当初的设计,虽然有很多地方仍待优化,但那是一条真实的成长轨迹。而我相信,你也正走在属于自己的技术之路上。

希望这篇来自实战经历的文章,能在你面对微服务难题时带来一丝启发和信心。如果你也在使用 Spring Cloud Alibaba,欢迎留言交流你的经验和困惑——互相学习,才能共同进步。


作者简介
我是老张,一线互联网公司资深 Java 工程师&架构师,从业多年专注于高可用、高性能后端系统的架构设计与优化,热爱开源技术,喜欢把复杂问题简单讲。

评论 0

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