从踩坑到稳定,我在 Spring Cloud Alibaba 实战中的成长之路

活泼_服务器
2025-06-30 10:59
阅读 358

引子:为什么选择 Spring Cloud Alibaba?

引子:为什么选择 Spring Cloud Alibaba?

去年的时候,我加入了一个新项目。这个项目的背景是一个大型电商平台,需要从头搭建微服务架构,并且要支持高并发、可扩展的业务需求。

当时我们在技术选型上遇到了一个问题:是继续使用传统的 Spring Cloud Netflix(Eureka、Ribbon、Feign、Zuul 等),还是尝试国内生态更贴近的 Spring Cloud Alibaba?我们团队里有经验丰富的老司机,也有刚接触微服务的新同学。最后在几个方案对比之后,决定尝试用 Spring Cloud Alibaba(以下简称 SCA)来做微服务治理的核心框架。

说实话,刚开始的时候心里没底,毕竟很多组件在国内用得多,但在英文社区里的文档和案例还不是很丰富。但随着一步步实践下来,也踩了很多坑、总结了很多经验,最终系统上线后表现良好,扛住了几次大促流量的冲击。

这篇文字就是想把我这一年的实战经验分享出来,希望能帮到一些还在观望或者准备上手 SCA 的朋友。


一、项目背景

一、项目背景

我们项目是一个典型的电商交易后台,涉及订单、商品、库存、支付等多个核心模块。整体要求如下:

  • 支持多租户体系,不同品牌商家的数据隔离;
  • 高可用、容错能力强,能够适应双十一、618等大促场景;
  • 要求快速迭代、模块解耦;
  • 技术栈要求以 Java 为主,Spring Boot + Spring Cloud 架构。

基于这些要求,我们选择了 Spring Cloud Alibaba 来作为微服务治理的基础框架,结合 Nacos、Sentinel、Seata、RocketMQ 这些组件来支撑服务注册发现、配置管理、限流熔断、分布式事务和异步消息通信。


二、遇到的主要挑战

二、遇到的主要挑战

挑战一:服务治理组件不熟悉导致上线初期故障频发

第一次上线是在一个灰度版本中,我们把部分服务拆成了微服务,结果上线第一天就出现了几个大问题:

  • Nacos 注册信息丢失:某个服务重启后没有注册回来,导致调用失败;
  • Ribbon 的负载策略出错:个别实例未健康检查就被调用,出现 404;
  • Sentinel 规则配置不当:有些接口限流规则太激进,直接返回了 block 页面,用户体验差;
  • Seata 分布式事务执行异常:某些分布式操作因为事务日志写入失败,卡死在提交阶段。

这些问题一度让我们非常被动,必须在生产环境下不断调整参数、排查问题。

挑战二:开发与运维割裂,缺乏统一监控

由于当时开发环境使用的是本地启动调试模式,而测试环境用了 Docker Compose 启动,正式环境是 Kubernetes 部署。三套环境差异很大,导致部署后经常出现各种奇奇怪怪的问题,比如:

  • 日志路径不对,应用启动后无法输出日志;
  • Nacos 地址配置错误,导致服务找不到;
  • 内存限制太小,频繁 Full GC。

虽然我们也有监控平台接入,但一开始做得不够完善,只能靠人工看日志排查问题。

挑战三:数据库设计不合理导致 Seata 使用困难

为了简化开发流程,我们一开始把数据库表设计得比较随意,表之间关联关系复杂、字段冗余严重,后来加上 Seata 做分布式事务时,经常出现“undo_log 表锁冲突”,甚至事务回滚失败等问题。


三、我们的解决方案

三、我们的解决方案

面对这些问题,我们逐步做了以下几方面的工作。

解决方案一:规范化服务注册与治理机制

使用 Nacos 作为统一注册中心

我们一开始使用的是 Eureka + Config Server 的组合,后来切换成 Nacos 是因为它自带了配置中心的功能,而且对国内网络环境更友好。

spring:
  application:
    name: order-service
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.1.100:8848
      config:
        server-addr: 192.168.1.100:8848
        file-extension: yaml

同时,我们在每个服务的健康检查端点 /actuator/health 加强了自定义逻辑,比如:

@Component
public class OrderHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        if (isDatabaseConnected()) {
            return Health.up().build();
        } else {
            return Health.down().withDetail("Error", "DB Connection Failed").build();
        }
    }

    private boolean isDatabaseConnected() {
        // 实际做 DB 检查逻辑
    }
}

这样可以更精准地控制服务是否健康,在 Ribbon 调用时避免调用不健康的实例。

采用 Sentinel 替代 Hystrix 做限流降级

SCA 推荐使用 Sentinel,它不仅支持简单的限流降级,还能进行实时监控、热点参数限流、系统自适应保护等。

我们通过 Sentinel Dashboard 配置限流规则,比如对订单创建接口设置每秒不超过 2000 次请求,超过自动降级为排队或拒绝。

@RestController
@RequestMapping("/order")
public class OrderController {

    @GetMapping("/create")
    @SentinelResource(value = "createOrder", fallback = "fallbackCreateOrder")
    public ResponseEntity<?> createOrder(@RequestParam String userId) {
        // 创建订单业务逻辑
    }

    public ResponseEntity<?> fallbackCreateOrder(String userId, Throwable ex) {
        return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).body("请稍后再试");
    }
}

解决方案二:统一部署环境与完善的监控体系

我们在上线前制定了统一的部署规范:

  • 所有服务都通过 Helm + Kubernetes 部署;
  • 每个服务都要暴露 Prometheus 监控指标;
  • 日志集中收集到 ELK;
  • 定期压测 + 全链路追踪(SkyWalking)

这大大减少了环境差异带来的问题,同时也方便我们做性能分析和故障定位。

解决方案三:重构数据库结构 + 合理使用 Seata

我们花了两周时间重新梳理了数据库表结构,做了以下几个优化:

  • 数据模型标准化,减少冗余;
  • 所有表都加了合理的索引;
  • 对参与分布式事务的表统一添加 xid 字段;
  • 使用 Seata 的 AT 模式,配合 undo_log 表做自动补偿;

Seata 客户端配置如下:

seata:
  enabled: true
  application-id: order-service
  tx-service-group: my_test_tx_group
  service:
    vgroup-mapping:
      my_test_tx_group: default
    grouplist:
      default: 192.168.1.100:8091
  config:
    type: nacos
    nacos:
      server-addr: 192.168.1.100:8848
      group: SEATA_GROUP

API接口文档-1

这样就能实现跨服务的事务一致性,例如下单扣库存这类业务场景。


四、关键代码和配置示例

示例 1:Sentinel 配置限流

@Configuration
@EnableWebMvc
public class SentinelConfig {

    @PostConstruct
    public void init() {
        WebCallbackManager.setUrlBlockHandler((request, response, ex) -> {
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
            try (ServletOutputStream os = response.getOutputStream()) {
                os.write("{\"code\":429,\"msg\":\"Too many requests\"}".getBytes(StandardCharsets.UTF_8));
                os.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }
}

示例 2:Seata 自动注入 xid

@GlobalTransactional
@Transactional
public void placeOrder(String userId, String productId) {
    // 创建订单
    createOrder(userId, productId);

    // 减少库存
    deductInventory(productId);
}

五、那些年我们一起踩过的坑

  1. Nacos 默认心跳间隔过长,健康检测不准

    • 初期我们遇到服务挂掉一段时间还没下线的情况。后来设置了心跳间隔和服务剔除策略:
    spring.cloud.nacos.discovery.heartbeat=5
    spring.cloud.nacos.discovery.metadata.healthy-check-timeout=3s
    
  2. Sentinel 控制台数据丢失,重启后规则消失

    • 最初我们都是在控制台上手动加规则,结果一重启全没了。后来改为持久化到 Nacos:
    sentinel:
      datasource:
        ds1:
          nacos:
            server-addr: 192.168.1.100:8848
            data-id: order-service-sentinel-rules
            group: DEFAULT_GROUP
            data-type: json
    
  3. RocketMQ 生产环境出现 broker 宕机后的重试机制失效

    • 我们原本设置的消息重试次数太少,也没有监听回调日志,后来加了如下配置:
    producer.setRetryTimesWhenSendFailed(3);
    producer.send(msg, (mqs, msg, arg) -> {
        // 失败回调记录日志
    }, null);
    

六、落地后的效果与收益

经过半年的持续优化和迭代,这套基于 Spring Cloud Alibaba 的微服务架构已经稳定运行多次活动,具体效果如下:

  • 平均 QPS 提升了 40%,响应时间降低 25%
  • 系统可维护性明显提升,新功能开发周期缩短了 30%
  • 故障定位效率提高了,基本可以在 5 分钟内确定问题节点
  • 在双十一大促期间成功抗住峰值流量,无重大事故

最关键的是,整个团队对于微服务的理解更深了,不再只是停留在“搭个 Eureka 就算搞定”的层面,而是真正理解了服务治理、限流降级、分布式事务这些核心概念。


七、几点建议送给正在学习的同学

  1. 别迷信官方文档,一定要自己跑通 demo

    很多时候文档讲得模糊不清,特别是中文资料更新不及时。你只有亲手跑了才会知道哪些地方有问题。

  2. 环境要统一,别等到上线再发现问题

    本地跑一套没问题,不代表测试环境就 OK。早点上 K8s 或 Docker Compose 统一部署方式,能省很多事。

  3. 监控永远是最值得投资的方向

    不管用 SkyWalking、Prometheus、还是阿里云 APM,只要能看到接口调用链、系统资源使用情况,排起问题来会轻松很多。

  4. 学会合理利用开源组件,但不要盲目依赖

    SCA 很强大,但也意味着你需要掌握更多组件的细节。比如 Sentinel、Seata、RocketMQ 等,它们的原理、配置、调优,都是要花时间研究的。

  5. 团队协作比技术更重要

    微服务不是一个人的事,前后端、运维、测试、产品都需要协同配合。很多时候我们的问题不是技术不行,而是沟通出了问题。


结语:成长总是在解决问题中发生的

负载均衡配置-2

回头看看这一年走过的路,真的是一边踩坑一边修复,一边学习一边总结。现在回想起来,其实这些问题本身并不可怕,关键是你有没有耐心去找到原因,是否有勇气面对不确定性。

Spring Cloud Alibaba 作为一个国产的技术栈,这几年确实发展得很快,特别是在电商、金融这种高并发场景下得到了广泛应用。如果你也在考虑要不要用它,我觉得完全可以试试看,只要做好前期的技术评估和规划,后期一定能体会到它的价值。

希望这篇文章能给你带来一些启发和信心。愿你在自己的技术道路上越走越远!


(全文约3147字)

评论 0

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