从零搭建微服务架构:Spring Cloud Alibaba 在生产中的实战经验分享

SystemArchitect
2025-06-24 14:24
阅读 559

引言:为何选择 Spring Cloud Alibaba?

作为一名后端开发工程师,在过去的几年里,我参与了多个基于微服务架构的企业级项目开发。而真正让我对 Spring Cloud Alibaba(以下简称 SCAlibaba)产生兴趣的,是在一个电商系统的重构项目中。

当时我们面临的问题很典型:单体应用性能瓶颈明显、代码臃肿难以维护、新功能上线周期长、故障隔离性差……种种问题促使我们决定将系统拆分为多个微服务模块,并引入一套合适的微服务治理框架来支撑整个体系。

起初,我们考虑的是经典的 Spring Cloud Netflix 套件(Eureka、Zuul、Feign 等),但在实际测试中发现了一些局限,比如 Eureka 已停止更新,社区活跃度下降,且与阿里云生态不兼容,不利于后续迁移到云原生环境。这时,SCAlibaba 凭借其良好的集成能力、稳定的性能表现和国内社区支持吸引了我们的注意。

今天我想以第一人称的角度,结合我们在一个真实项目中的落地实践,带大家看看如何在生产环境中使用 Spring Cloud Alibaba,以及我们踩过的那些坑和收获的经验。


项目背景:一个典型的电商系统重构案例

负载均衡配置-1

我们的项目是一个电商平台的后端重构工作,目标是将原先的单体 Java Web 应用改造为多个独立部署的微服务模块,包括用户中心、商品中心、订单中心、库存中心、支付中心、网关等核心模块。

业务量方面,日均 UV 大约在 20-30W 之间,高峰期并发请求可达 1w+,属于中小型规模但对稳定性和响应速度要求较高的场景。

团队背景:由 8 人组成的后端研发小组,技术栈以 Java 为主,大部分成员有 Spring Boot 和部分 Spring Cloud 使用经验,但对于 SCAlibaba 几乎都是从零开始。


面临的主要挑战

在转型过程中,我们遇到了以下几个核心问题:

1. 微服务间通信不稳定

最初我们尝试使用 Feign + RestTemplate 进行远程调用,但由于服务数量较多,经常出现服务找不到、调用失败、超时等问题。尤其是在服务启动或重启期间,容易导致连锁故障。

2. 服务注册发现机制复杂

采用 Eureka 初期还能应对简单情况,但随着服务数量增长,出现了服务注册延迟、节点剔除不及时、元数据管理混乱等情况。

3. 接口安全性缺乏保障

各服务之间的调用没有统一认证机制,存在越权访问的风险。

4. 分布式配置管理缺失

多环境下配置文件差异大,手动管理极易出错。

5. 没有统一的服务网关

每个服务都需要自己处理跨域、限流、鉴权等通用逻辑,代码冗余严重。

6. 监控告警手段匮乏

出了问题无法快速定位,只能靠日志人工排查。

这些问题让我们意识到,如果想把微服务架构跑起来并稳定下去,光靠基础 Spring Cloud 是远远不够的,必须借助成熟的中间件和服务治理工具。


技术选型与方案设计:为什么选 SCAlibaba?

我们对比了多个解决方案后最终锁定了 Spring Cloud Alibaba 的组合套件,主要包括以下组件:

组件名称 功能描述
Nacos 服务注册/发现 & 配置中心
Sentinel 流量控制、熔断降级
Seata 分布式事务
RocketMQ 异步消息队列
Gateway API 网关,负责路由、鉴权、限流等
OpenFeign + LoadBalancer 声明式远程调用

这整套组合刚好覆盖了微服务架构所需的关键能力,而且组件之间协同良好,特别是与 Nacos 的集成非常自然。

此外,这些组件大多数都有官方文档支持和社区反馈,对于中国企业来说本地化程度也更高。


实施过程与关键技术实现

下面我来详细讲讲我们是如何一步步搭建这套系统的,重点介绍几个关键环节。

1. 构建统一服务注册与发现机制 —— Nacos

我们首先搭建了 Nacos 作为所有服务的注册中心和统一配置中心。

安装方式:

git clone https://github.com/alibaba/nacos.git
cd nacos && git checkout develop
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U

然后进入 distribution/target/nacos-server-$version 启动 standalone 模式即可。

小插曲:第一次搭建时我们选择了集群模式,结果配置同步问题折腾了半天,最后果断改回单机先跑通逻辑。建议新手初期不要急着做高可用,先把流程理顺。

客户端接入(以用户服务为例):

<!-- pom.xml 添加 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2.2.9.RELEASE</version>
</dependency>
# application.yaml
server:
  port: 8081
spring:
  application:
    name: user-service
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

加上这个配置后,服务一启动就会自动注册到 Nacos 中。其他服务通过 @LoadBalanced 注解加 Feign 调用,即可完成负载均衡调用:

@Bean
public FeignClientConfig feignClientConfig() {
    return new FeignClientConfig();
}

@RestController
public class UserController {

    @Autowired
    private OrderServiceClient orderServiceClient;

    public ResponseEntity<?> getUserOrders(Long userId) {
        return ResponseEntity.ok(orderServiceClient.getUserOrders(userId));
    }
}

2. 接入分布式配置中心 —— Nacos Config

我们将所有配置抽取到 Nacos 中进行集中管理。例如数据库连接信息、Redis 地址、短信模板 ID 等。

添加依赖:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>2.2.9.RELEASE</version>
</dependency>

创建 bootstrap.yml:

server:
  port: 8081
spring:
  application:
    name: user-service
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        extension-configs:
          - data-id: mysql-config.yaml
            group: DEFAULT_GROUP
            refresh: true

这样在 Nacos Config Server 中配置好 mysql-config.yaml 文件后,就能实时推送到各个服务实例上。

提示:一定要记得加上 extension-configs 这个配置项,否则默认只会加载名为 ${application}.yaml 的配置文件。

3. 构建统一网关 —— Gateway + Nacos + Sentinel

我们选用 Spring Cloud Gateway 作为网关层,并接入 Nacos 注册中心:

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
          filters:
            - StripPrefix=1
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

为了让网关具备限流和熔断的能力,我们又集成了 Sentinel:

添加依赖:

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

Sentinel 控制台启动方式:

java -jar sentinel-dashboard.jar

浏览器访问 localhost:8080 登录后,在服务端配置如下内容接入 Sentinel 客户端:

sentinel:
  transport:
    dashboard: localhost:8080

随后在 Sentinel 控制台上就可以看到所有接入的服务,并可以对网关接口设置限流规则:

4. 分布式事务难题解决 —— Seata AT 模式初探

在订单服务与库存服务联动操作时,需要实现“扣库存减下单”的原子操作,否则会出现一致性问题。

我们采用了 Seata 的 AT 模式来实现两阶段提交。以下是具体步骤:

  1. 初始化 Seata Server(TC)

    下载并运行 seata-server,修改 file.conf 设置事务组和存储方式为 DB。

  2. 在各服务中添加 Seata 客户端依赖:

    <dependency>
        <groupId>io.seata</groupId>
        <artifactId>seata-spring-boot-starter</artifactId>
        <version>1.5.2</version>
    </dependency>
    
  3. 配置事务组名和 TC 地址:

    seata:
      enabled: true
      application-id: inventory-service
      tx-service-group: my_tx_group
      service:
        vgroup-mapping:
          my_tx_group: default
        grouplist:
          default: 127.0.0.1:8091
    
  4. 在业务方法中加入注解即可开启全局事务:

    @GlobalTransactional
    public void createOrderAndReduceStock(OrderDTO dto) {
        // 创建订单逻辑
        // 扣减库存逻辑
    }
    

虽然初期调试有点小波折(比如要手动加 undo_log 表、事务协调器地址要正确等等),但整体效果还不错。

5. 异步解耦利器 —— RocketMQ

为了降低服务间的强耦合关系,我们引入了 RocketMQ 来处理异步通知类任务,例如发送短信、记录日志、处理退款回调等。

接入 RocketMQ 生产者示例:

@Component
public class MessageProducer {

    private final RocketMQTemplate rocketMQTemplate;

    public MessageProducer(RocketMQTemplate rocketMQTemplate) {
        this.rocketMQTemplate = rocketMQTemplate;
    }

    public void sendMsg(String topic, String msg) {
        rocketMQTemplate.convertAndSend(topic, msg);
    }
}

消费者监听示例:

@Service
@RocketMQMessageListener(topic = "ORDER_CREATED_TOPIC", consumerGroup = "order-consumer-group")
public class OrderConsumer implements RocketMQListener<String> {

    @Override
    public void onMessage(String message) {
        // 处理订单创建后的消息逻辑
    }
}

配合 Kafka 可能更成熟一些,但我们考虑到未来会迁移至阿里云平台,因此优先选择 RocketMQ。


踩坑经验分享

虽然 Spring Cloud Alibaba 整体体验不错,但在实际落地过程中还是遇到了不少“雷区”,这里我把最有代表性的几个总结一下。

⚠️ 1. Sentinel 规则不持久化的问题

刚开始时,我们设置了若干限流规则,第二天一看全都丢了!原因是默认 Sentinel Dashboard 使用的是内存模式。

解决方案:

接入 Nacos 存储限流规则,通过如下配置让 Sentinel 支持持久化:

sentinel:
  datasource:
    ds1:
      nacos:
        server-addr: 127.0.0.1:8848
        data-id: ${spring.application.name}-sentinel
        group: DEFAULT_GROUP
        data-type: json

⚠️ 2. Seata 启动异常:No available service

Seata TC 无法找到时,报错:"No available service 'tc' found"

排查方法:

确认 registry.conf 是否配置正确,是否启用 Nacos 并填写正确的服务地址;

同时要确保 Seata TC 已经成功注册到了 Nacos 中,否则客户端拿不到服务列表。

⚠️ 3. Feign 调用失败:LoadBalancerException

远程调用报错:"LoadBalancerException: No instances available for service"

分析原因:

通常是服务还未完成注册或者 Nacos 客户端未拉取最新服务实例列表。

解决方案:

  • 等待一段时间再试;
  • 手动刷新 Nacos 服务注册状态;
  • 在网关或客户端增加重试机制。

⚠️ 4. Nacos 配置热更新失败

虽然配置启用了 refresh,但有时修改后并不生效。

检查点:

  • 是否在 Java 类中使用了 @RefreshScope 注解;
  • 对应 bean 是否被 spring 容器管理;
  • 配置文件名是否与 data-id 匹配;
  • Sentinel 是否影响了配置刷新。

项目成果与收益总结

经过大约两个半月的开发与打磨,我们顺利完成了整个微服务架构的搭建和部署。主要成果如下:

✅ 成功将原有单体拆分为 7 个独立可扩展服务
✅ 实现服务间标准化通信与限流熔断机制
✅ 建立统一网关入口,支持权限验证、流量限制等常见需求
✅ 配置集中管理,支持动态刷新,提升了运维效率
✅ 分布式事务初探取得成功,避免资金损失风险
✅ 日志监控体系基本成型,便于后期优化和排错

上线后,我们观察到以下几点显著提升:

🔹 服务响应变快:各服务按需启动,资源占用更合理
🔹 故障隔离增强:某服务异常不会影响整个系统
🔹 灰度发布变得可行:支持 A/B 测试与滚动更新
🔹 部署灵活性提高:可以按模块灵活部署,适应不同环境
🔹 团队协作更顺畅:各模块独立开发,减少代码冲突


我的建议与注意事项

如果你也在考虑使用 Spring Cloud Alibaba 来构建自己的微服务架构,我愿意分享几点经验和建议:

📌 1. 先搞清楚你要什么,别上来就全量堆叠组件

SCAlibaba 功能强大,但并不是所有组件都适合你的项目。根据实际需求选择必要的组件,逐步引入,不然很容易把自己埋死在复杂的配置中。

📌 2. 不要低估前期的技术学习成本

Nacos、Sentinel、Seata 等每一个组件都有一套自己的概念和配置方式,团队成员如果没有足够的学习时间,容易掉进各种坑里。建议安排培训或内部文档沉淀。

📌 3. 让配置中心尽早介入,越早越好

配置中心不仅仅是管理环境变量,它还可以帮助你实现参数动态调整、灰度发布、AB 测试等功能。越早集成进来,后面的好处越多。

📌 4. 做好监控和报警体系建设

微服务架构一旦上线,服务数量暴涨,监控显得尤为重要。建议至少集成 Prometheus + Grafana 做基础监控,并搭配告警系统。

📌 5. 关注版本兼容性

SCAlibaba 更新频繁,不同版本之间可能存在兼容性问题。尤其要注意 Spring Boot、Spring Cloud、SCAlibaba 的版本组合。推荐参考官方文档的版本对应表。


结语:技术的路永远在路上

写到这里,我已经回忆起那段夜以继日与 Nacos、Sentinel 作斗争的日子了。虽然有过抓狂、也有过失眠,但每当看到系统逐渐稳定运行、指标稳步向好时,内心又充满了成就感。

Spring Cloud Alibaba 在我们项目中扮演了至关重要的角色,它不仅帮助我们实现了架构升级,更重要的是,它教会了我们如何用工程化的思维去解决复杂系统带来的挑战。

技术的路永无止境,希望这篇文章能给你带来一些启发和方向。如果你正在用 SCAlibaba 或打算上手,欢迎留言交流更多实战经验。我们可以一起成长!


文章字数统计:约 3960 字
关键词标签: #SpringCloudAlibaba #微服务架构 #Nacos #Sentinel #生产实践 #架构演进

评论 0

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