在国企用 Spring Cloud Alibaba 搞微服务,真香还是踩坑?

低调写码
2025-12-28 00:47
阅读 2422

大家好,我是个双休不加班的国企程序员,坐标上海,住公司附近步行十分钟那种“理想打工人”配置。每天八点半起床、九点到工位、泡杯枸杞茶、打开 VSCode(插件多到启动要三秒),然后开始写代码——听起来是不是有点凡尔赛?但现实是:项目 deadline 逼近时,我也得陪产品经理一起改需求到晚上九点,只不过第二天能补休罢了。

最近半年,我们团队从单体 Spring Boot 架构往微服务迁移,技术栈选了 Spring Cloud Alibaba(SCA)。原因嘛,一方面是集团统一技术路线,另一方面也是因为 Nacos + Sentinel + Seata 这套组合拳在社区和国内生态里确实成熟。今天这篇文章,就想聊聊我们在生产环境落地 SCA 的一些真实体验——有架构设计上的思考,也有半夜被告警电话叫醒的血泪教训。


为啥不用 Spring Cloud Netflix?Go 和 Python 都在抢饭碗了

说起来有点扎心:就在我们决定上 SCA 的时候,隔壁新成立的数据中台团队已经用 Go 写了一套轻量级微服务网关,性能直接碾压我们的 Zuul;而算法组那边更狠,Python + FastAPI 做特征服务,接口响应稳定在 20ms 以内,测试同学跑压测都惊了。

这让我一度怀疑:Java 微服务是不是过时了?但冷静下来一想,我们系统核心是交易和风控,强一致性、事务支持、企业级监控这些刚需,Go 和 Python 虽然快,但在复杂业务场景下还是略显“玩具感”。尤其是涉及到分布式事务(比如用户下单+扣库存+发券),Seata 这种成熟的方案还是 Java 生态更稳。

所以最终拍板:主业务系统继续用 Java + SCA,边缘服务可以灵活用 Go/Python。这种“混合架构”其实在大厂很常见,但对我们这种传统国企来说,算是一次不小的突破。


Nacos 作为注册中心 & 配置中心:别信文档,信日志

Nacos 是 SCA 的核心组件,我们一开始以为“开箱即用”,结果上线第一天就翻车。

问题一:配置热更新失效

开发环境一切正常,但生产环境修改 application-prod.yml 后,服务居然没 reload!查了半天才发现:@RefreshScope 注解只对 @Component 生效,对 @ConfigurationProperties 不生效。后来改成这样才搞定:

@Configuration
@RefreshScope
public class DynamicConfig {
    @Value("${feature.toggle.new-ui:false}")
    private boolean newUiEnabled;

    // 注意:不能用 ConfigurationProperties,否则不刷新
}

📌 经验:生产环境一定要做“配置变更 -> 服务行为变化”的端到端验证,别光看 Nacos 控制台显示“已发布”。

问题二:服务注册延迟

有一次发布新版本,运维发现流量没切过去,一看 Nacos 控制台,新实例居然没注册!原来是我们启用了 K8s 的 readiness probe,但探针路径 /actuator/health 返回 DOWN(因为数据库连接池还没初始化完),导致 Pod 被标记为 NotReady,Nacos 客户端根本没机会注册。

解决方案:把 readiness probe 改成只检查端口是否监听,健康检查逻辑交给 Nacos 的心跳机制处理。

# deployment.yaml
readinessProbe:
  tcpSocket:
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 10

Sentinel 流控:别等大促才想起它

去年双11前一周,领导突然召集会议:“今年要冲 GMV,系统必须扛住 3 倍流量!” 我心里一咯噔——我们的订单服务之前从来没做过压测。

赶紧给核心接口加上 Sentinel 注解:

@SentinelResource(value = "createOrder", 
    blockHandler = "handleCreateOrderBlock",
    fallback = "createOrderFallback")
public Order createOrder(OrderRequest request) {
    // 业务逻辑
}

// 限流时的兜底方法
public Order handleCreateOrderBlock(OrderRequest request, BlockException ex) {
    log.warn("订单创建被限流", ex);
    throw new BizException("系统繁忙,请稍后再试");
}

但问题来了:Sentinel 控制台默认是内存模式,重启就丢规则!生产环境必须持久化到 Nacos 或 Apollo。

我们选了 Nacos,配置如下:

# bootstrap.yml
spring.cloud.sentinel.datasource.ds1.nacos.server-addr=${nacos.server-addr}
spring.cloud.sentinel.datasource.ds1.nacos.data-id=sentinel-rules
spring.cloud.sentinel.datasource.ds1.nacos.group-id=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds1.nacos.rule-type=flow

然后在 Nacos 里新建一个 JSON 配置:

[
  {
    "resource": "createOrder",
    "limitApp": "default",
    "grade": 1,
    "count": 50,
    "strategy": 0,
    "controlBehavior": 0
  }
]

💡 提示:grade=1 表示 QPS 模式,count=50 就是每秒最多 50 次请求。建议先设宽松一点,再根据压测结果调整。

双11当天,系统峰值 QPS 达到 120,Sentinel 自动熔断了非核心接口(比如“查询用户历史订单”),保住了下单链路。那一刻,我真的感谢阿里开源了这套东西。


Seata 分布式事务:小心“假成功”

我们有个典型场景:用户支付成功后,要同时更新订单状态、增加积分、发通知。三个操作跨三个 DB,必须保证一致性。

最初用 Seata 的 AT 模式,代码看起来很美:

@GlobalTransactional
public void handlePaymentSuccess(String orderId) {
    orderService.updateStatus(orderId, "PAID");
    pointService.addPoints(userId, 100);
    messageService.sendNotification(userId, "支付成功");
}

但上线后发现:有时订单状态更新了,积分却没加!查 Seata 日志发现 TM(事务管理器)超时了,默认 60 秒,而我们的 pointService 调用外部 API 比较慢。

解决方案:

  1. 调大全局事务超时时间@GlobalTransactional(timeoutMills = 120000)
  2. 关键服务内部做幂等:比如积分表加唯一索引 (user_id, biz_id, biz_type),防止重复加
  3. 异步解耦非核心操作:发通知这种其实可以扔 MQ,不在全局事务里

现在我们的策略是:强一致性走 Seata,弱一致性走 MQ + 补偿任务。毕竟不是所有场景都需要 ACID。


混合架构下的服务治理:Java、Go、Python 如何共存?

前面提到,我们允许边缘服务用 Go/Python。但这就带来一个问题:Nacos 只能注册 Java 服务?

其实不然!Nacos 提供了 OpenAPI,任何语言都能注册:

比如 Python 服务注册示例:

from nacos import NacosClient

client = NacosClient(SERVER_ADDRESSES, namespace=NAMESPACE)
client.add_naming_instance(
    "user-feature-service",
    "10.244.1.10",
    8000,
    metadata={"version": "v1.2"}
)

但要注意:非 Java 服务无法使用 Sentinel 注解!所以我们约定:

服务类型 注册中心 配置中心 流控方案
Java (核心) Nacos Nacos Sentinel
Go/Python (边缘) Nacos 自研 Agent K8s HPA + 自定义指标

边缘服务的流控靠 K8s 的 HorizontalPodAutoscaler,根据 CPU 或自定义指标(如 queue length)扩缩容。虽然不如 Sentinel 精细,但够用。


生产环境运维经验:别让监控睡大觉

在国企,最怕的不是 Bug,而是 线上出问题没人知道。所以我们给 SCA 服务配了三重保障:

  1. Nacos 实例健康检查:每 5 秒心跳一次,超时自动剔除
  2. Prometheus + Grafana 监控
    • JVM 内存、GC 次数
    • Sentinel block qps
    • Seata 全局事务成功率
  3. 企业微信告警:关键指标异常自动 @ 值班人

特别提醒:别忘了监控 Nacos 本身!我们曾因 Nacos MySQL 连接池耗尽,导致所有服务注册失败。后来给 Nacos 加了独立监控面板,包含:

  • 配置发布次数
  • 服务实例数趋势
  • MySQL 连接使用率

总结:SCA 不是银弹,但很适合我们

回顾这半年,Spring Cloud Alibaba 让我们以较低成本实现了微服务治理,尤其是在配置管理、流量防护、分布式事务这几个痛点上,省了大量造轮子的时间。

但它也不是万能的:

  • 学习曲线陡峭,新人上手慢
  • 部分组件(如 Seata)对 DB 有侵入(需要 undo_log 表)
  • 社区版功能有限,高级特性得买商业版(比如 Nacos 集群自动扩缩容)

不过对我们这种追求稳定、迭代节奏慢的国企团队来说,SCA + K8s + 混合语言架构,算是找到了一个平衡点:核心系统稳如老狗,创新服务又能快速试错。

最后吐槽一句:上周五下班前,产品经理又提了个“简单需求”——“能不能在下单时顺便预测用户下次购买时间?” 我瞥了眼工位上的 Go 语言书,默默打开了 VSCode……或许,是时候让 Python 模型服务也接入 Nacos 了?

(完)

作者:一个在国企写 Java 的普通程序员
工具:VSCode + Remote SSH 连公司跳板机
时间:2024 年 6 月,一个没有加班的周五晚上

评论 0

最热最新
暂无评论
低调写码Lv.1
0
影响力
0
文章
0
粉丝