Spring Cloud Alibaba 在百度搜索业务中的落地实战

分布式背锅侠
2025-12-27 11:45
阅读 742

上周五晚上十点半,我还在工位上调试一个 Nacos 配置推送失败的线上问题,耳机里放着 Lo-fi Hip Hop,脑子里却在想明天 LeetCode 要刷哪道题——毕竟跳槽季快到了,简历上总不能只写“精通百度内部框架”吧。

说来惭愧,在百度干了两年搜索算法相关的工作,虽然天天和高并发、低延迟打交道,但微服务这块其实一直用的是公司自研的中间件体系。直到去年团队接了个外部合作项目,要求用开源技术栈交付,我才被迫重拾 Spring Cloud,而且是 Spring Cloud Alibaba(SCA) 这个在国内企业圈越来越火的全家桶。

一开始我是抗拒的。不是说 SCA 不好,而是“又要学新东西”这件事本身就很反人性,尤其当你白天还要调 CTR 模型、晚上被产品经理追着问“为什么排序结果昨天还好好的今天就崩了”的时候。但转念一想:这玩意儿现在几乎成了国内 Java 微服务的事实标准,面试八股文里都快成必考项了,不搞懂它,跳槽时连简历初筛都过不了。于是咬咬牙,边查文档边改代码,硬是把一套 SCA 架构跑起来了。


为什么选 SCA?不只是“国产替代”那么简单

很多人以为 SCA 就是 Spring Cloud 的“阿里定制版”,用来替代 Eureka、Hystrix、Zuul 这些 Netflix 套件。但在我实际落地过程中发现,它的优势远不止于此。

首先,Nacos 真的香。我们之前用 Consul 做服务注册与发现,配置管理还得另搭 Apollo,运维成本高得离谱。而 Nacos 一个组件搞定注册中心 + 配置中心,还支持灰度发布、监听推送、多环境隔离。最关键的是,它对中文文档友好,社区活跃——这对赶 deadline 的打工人太重要了。

其次,Sentinel 的流量治理能力比 Hystrix 更贴近生产场景。Hystrix 只能做熔断降级,但 Sentinel 支持 QPS/线程数限流、系统自适应保护、热点参数限流,甚至还能和 Nacos 联动实现动态规则下发。去年双11期间,我们就靠它扛住了合作方突发的 5 倍流量冲击,没让下游搜索接口被打垮。

最后一点很现实:求职市场认这个。我最近投了几家大厂,JD 里清一色写着“熟悉 Spring Cloud Alibaba 优先”。哪怕你只会背概念,也比完全没听过强。所以从职业发展的角度看,花时间搞懂 SCA,ROI(投入产出比)极高。


落地过程:从“Hello World”到线上事故复盘

我们的项目是一个面向外部客户的搜索 API 网关,需要对接多个后端微服务(包括我们的核心排序服务)。架构图大致如下:

Client → [Spring Cloud Gateway] → [Nacos 注册中心]
                              ↘
                               → [Search Service A]
                               → [Search Service B]
                               → [User Profile Service]

第一个坑:Nacos 配置中心的“假同步”

本地跑得好好的,一上测试环境就报 com.alibaba.nacos.api.exception.NacosException: failed to req API。排查半天才发现,Nacos 客户端默认用的是内网地址,而我们的测试环境网络策略限制了跨 VPC 访问。解决方法很简单:在 bootstrap.yml 里显式指定 server-addr:

spring:
  cloud:
    nacos:
      config:
        server-addr: nacos.test.internal:8848
        namespace: search-prod
        group: DEFAULT_GROUP

但更隐蔽的问题是配置刷新失效。我们用 @RefreshScope 注解标记了配置类,但某些 Bean 并没有实时更新。后来才明白:@RefreshScope 只对 Spring 管理的单例 Bean 有效,如果你自己 new 了一个对象,或者用了静态变量存配置,那对不起,刷新不了。最后我们统一改用 @ConfigurationProperties + 监听 RefreshEvent 手动处理。

第二个坑:Sentinel 规则持久化到 Nacos

默认情况下,Sentinel 控制台配置的限流规则是存在内存里的,服务一重启就没了。这在线上简直是灾难。所以我们必须把规则持久化到 Nacos。

实现起来不算复杂,但文档有点散。核心是两点:

  1. 在应用端引入 sentinel-datasource-nacos 依赖
  2. 在 Nacos 上创建对应的规则配置(Data ID 格式固定)

我们还写了个自动化脚本,在 CI/CD 流程里自动推送初始规则,避免人工遗漏。附上一段关键配置:

// SentinelRuleNacosConfig.java
@Configuration
public class SentinelRuleNacosConfig {
    
    @Bean
    public DataSource<String, List<FlowRule>> flowRuleDataSource() {
        ReadableDataSource<String, List<FlowRule>> ds = 
            new NacosDataSource<>("nacos.test.internal:8848", 
                                  "search-prod", 
                                  "sentinel-flow-rules", 
                                  source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));
        return ds.getProperty();
    }
}

第三个坑:Dubbo 与 Feign 的混用冲突

SCA 默认集成了 Dubbo,但我们有些老服务还是用 OpenFeign 调用的。结果启动时报 No qualifying bean of type 'xxx' available。原因是 SCA 的自动配置把 FeignClient 给“劫持”了。

解决方案是显式排除 Dubbo 的自动装配:

@SpringBootApplication(exclude = {DubboAutoConfiguration.class})

或者更精细地控制:只在需要 Dubbo 的模块启用它。这点在混合架构迁移期特别重要——别指望一步到位,现实往往是“新旧共存”。


生产环境运维经验:这些细节决定成败

上线后,我们总结了几条血泪教训:

问题 现象 解决方案
Nacos 心跳超时 服务频繁上下线 调整 nacos.client.naming.heartbeat.intervaltimeout 参数
Sentinel 控制台看不到机器 IP 被 NAT 转换 启动时加 -Dcsp.sentinel.app.type=1 -Dcsp.sentinel.api.port=8719
配置变更后日志刷屏 日志级别太高 关闭 com.alibaba.nacos.client.config 的 DEBUG 日志

另外,务必给所有微服务加上健康检查接口。我们用 Spring Boot Actuator 暴露 /actuator/health,配合 K8s 的 liveness/readiness probe,避免流量打到未就绪实例上。

数据库方面,虽然 SCA 不直接管 DB,但我们在设计接口时坚持两个原则:

  1. 查询接口必须带 timeout(通过 Feign 的 ReadTimeout 控制)
  2. 写操作必须幂等(用 Redis 分布式锁 + 请求 ID 去重)

写在最后:技术选型背后的职场思考

折腾完这套 SCA 架构,我最大的感受是:开源技术栈的价值不仅在于功能,更在于“可解释性”。当你要向新公司证明自己有微服务能力时,说“我用过百度内部 XXX 框架”没人懂,但说“我用 Nacos + Sentinel 搞定了高可用网关”,HR 和面试官眼睛都会亮一下。

所以,如果你也在准备跳槽,别只刷算法题。花点时间跑通一套主流开源架构,写篇博客、录个视频,甚至只是整理一份踩坑清单,都能让你的简历脱颖而出。毕竟,会用工具的人很多,但能讲清楚“为什么这么用”的人很少

现在,我的 SCA 项目已经稳定运行三个月,QPS 峰值 5000+,P99 延迟 <80ms。虽然比不上百度内部系统的千万级并发,但至少——下次面试时,我能挺直腰板说:“Spring Cloud Alibaba?我生产环境玩过。”

对了,LeetCode 今天刷了吗?

评论 0

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