从 Flutter 到 Spring Cloud Alibaba:一个 Android 转型者的跨端后端实战手记

诗和远方
2025-12-12 16:28
阅读 707

大家好,我是老K,前 Android 开发一枚,现在主攻 Flutter + 后端混合开发。坐标杭州,混迹于阿里网易生态周边,靠 ChatGPT 和 Claude 活命(不然根本卷不动)。最近半年被拉去搞微服务架构重构,硬着头皮啃了 Spring Cloud Alibaba(SCA),今天就来聊聊我们在生产环境里踩过的坑、省下的资源,以及那些让我半夜三点想砸键盘的瞬间。


为什么一个“前端仔”要碰 SCA?

说来话长。去年双11前,团队接了个紧急需求:把原来单体架构的老 Java 后台拆成微服务,支撑多端(App、小程序、H5)高并发访问。领导一拍大腿:“你不是会写点 Java 吗?上!”——我一脸懵:我上一次写 Spring Boot 还是在培训班做 TodoList!

但没办法,Flutter 写多了也想摸点后端,而且杭州这边大厂都在推云原生+微服务,跳槽简历没点 SCA 经验根本过不了 HR 筛。于是边查文档边问 Claude,硬是把 Nacos、Sentinel、Seata 全啃了一遍。


实战场景:订单系统雪崩,差点背锅

项目上线第一周,测试同学美滋滋地报喜:“压测通过!”,结果周五晚上九点,线上报警炸了——订单创建接口超时率飙升到 40%

日志一看,是库存服务响应慢,拖垮了整个链路。更惨的是,因为没做熔断,用户疯狂重试,直接把数据库连接池打爆。运维小哥在群里咆哮:“谁写的代码?这要是双11就完了!”

那一刻,我真的想删库跑路。

痛定思痛,我们决定全面接入 Spring Cloud Alibaba,重点用好三个组件:

  • Nacos:服务注册与配置中心
  • Sentinel:流量控制与熔断降级
  • Seata:分布式事务(虽然最后没全用上)

资源优化:从“堆机器”到“精打细算”

以前我们遇到性能问题就加机器,老板看了直摇头。这次重构,目标很明确:用最少的资源扛住峰值流量

1. Nacos 配置动态化,告别“改配置重启”

以前改个超时时间都要发版,运维和开发互相甩锅。现在所有配置扔进 Nacos,实时生效。

# bootstrap.yml
spring:
  application:
    name: order-service
  cloud:
    nacos:
      config:
        server-addr: ${NACOS_HOST}:${NACOS_PORT}
        file-extension: yaml

比如订单超时时间,直接在 Nacos 控制台改:

order.timeout.seconds: 30

Java 代码里加个 @RefreshScope 就自动刷新。再也不用求运维半夜上线了!

📌 小贴士:记得开启 Nacos 的权限控制!我们一开始没设密码,被安全扫描扫出高危漏洞,差点被通报……

2. Sentinel 熔断降级,保住核心链路

这是救我们命的功能。我们给创建订单这个核心接口配了规则:

  • QPS > 1000 时,自动拒绝多余请求
  • 库存服务 RT > 500ms,10秒内失败率超 50%,立刻熔断

配置如下(通过 Sentinel Dashboard 可视化操作):

资源名 阈值类型 阈值 熔断策略
POST:/api/order/create RT 500ms 慢调用比例
inventory-service 异常比例 0.5 异常比例

效果立竿见影:即使库存服务挂了,订单服务也能快速失败并返回友好提示,不会拖垮整个系统

有一次模拟故障,库存服务宕机,Sentinel 在 3 秒内触发熔断,用户看到“库存服务繁忙,请稍后再试”,而其他功能(比如查订单)完全正常。产品经理居然夸我们“体验做得好”……(内心:要不是 Sentinel,你早就被投诉炸了)


数据库与接口设计:别让微服务变“微麻烦”

拆微服务最怕什么?分布式事务数据一致性

我们最初想用 Seata 的 AT 模式,但发现对 DB 性能影响较大(需要 undo_log 表 + 全局锁)。后来妥协方案:

  • 非核心操作异步化:比如发优惠券、记录日志,扔进 RocketMQ
  • 核心链路强一致:订单+支付用本地事务 + 补偿机制(定时对账)
  • 接口幂等性强制要求:所有写接口必须带 requestId,防止重复提交

举个例子,创建订单接口:

@PostMapping("/create")
public Result<OrderDTO> createOrder(@RequestBody CreateOrderRequest req) {
    // 1. 校验 requestId 幂等
    if (idempotentService.exists(req.getRequestId())) {
        return Result.success(alreadyCreatedOrder);
    }
    
    // 2. 本地事务:扣库存(调用库存服务,失败则抛异常)
    inventoryClient.decrease(req.getSkuId(), req.getCount());
    
    // 3. 创建订单(本地 DB)
    Order order = orderService.create(req);
    
    // 4. 标记幂等
    idempotentService.mark(req.getRequestId(), order.getId());
    
    // 5. 异步发消息(解耦)
    mqProducer.send("order.created", order.getId());
    
    return Result.success(order.toDTO());
}

这样既保证了关键路径的一致性,又避免了 Seata 带来的复杂性和性能损耗。


生产运维经验:监控不到位,等于裸奔

SCA 不是银弹,可观测性才是微服务的生命线。

我们搭了三件套:

  1. Prometheus + Grafana:监控 JVM、QPS、RT
  2. SkyWalking:链路追踪,一眼看出哪个服务拖后腿
  3. ELK:日志集中管理,关键词告警(比如“Timeout”、“Exception”)

有一次半夜报警,Grafana 显示订单服务 CPU 突然飙到 90%。通过 SkyWalking 一看,是某个新接口在循环里调用了远程服务,O(n) 变成 O(n²)。5 分钟定位,10 分钟回滚,比以前靠 grep 日志快了十倍。


效果如何?资源省了 40%,稳定性拉满

重构上线三个月,数据说话:

指标 旧架构 SCA 新架构 提升
服务器数量 12 台 7 台 ↓ 42%
订单接口 P99 RT 1200ms 320ms ↓ 73%
故障恢复时间 30+ 分钟 < 2 分钟 ↑ 15x
发布频率 每周 1 次 每天 3-5 次 ↑ 20x

最关键的是——再也没因为级联故障背过锅


最后几句大实话

作为从客户端转过来的“伪后端”,我深刻体会到:微服务不是技术炫技,而是为了可控、可运维、可扩展

Spring Cloud Alibaba 在国内生态确实香,Nacos 比 Eureka 更适合我们这种中小团队(自带配置中心!),Sentinel 的实时流控简直是救命稻草。但别盲目上 Seata,先想想业务是否真需要强一致。

另外,别信“一套框架走天下”。我们甚至在某些边缘服务里用 Go 写了轻量 API,和 Java 微服务共存——能解决问题的技术,就是好技术

如果你也在杭州,正被微服务折磨,或者想从移动端转型全栈,欢迎留言交流。顺便,有内推机会吗?(狗头保命)


彩蛋:上周五加班到十点,终于把 Nacos 集群从单节点升级完成。走出公司,西湖边吹着风,突然觉得——
写代码虽然苦,但看到系统稳如老狗,还是有点小骄傲的。

评论 0

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