Spring Cloud从零开始:微服务入门指南(附真实踩坑记录)
入职新公司两个月,我终于理解了什么叫“微服务地狱”——不是技术难,而是没人告诉你怎么从单体应用跳出来,还不摔个狗吃屎。
上周五晚上九点半,我盯着屏幕里一个报错信息发呆:
com.netflix.client.ClientException: Load balancer does not have available server for client: user-service
这行字背后,是我连续三天试图把旧系统拆成微服务的血泪史。而更离谱的是,我们组的产品经理还在群里@我说:“下周三上线,别忘了哦~ 😊”
为什么突然要搞微服务?
说实话,刚来的时候我主要写 Python 爬虫脚本,抓点公开数据、做些 ETL 清洗,舒服得很。但两周前,CTO在全员会议上甩出一句话:“老系统扛不住双11流量了,必须上微服务。”
于是,我和另外两个后端被临时拉进“架构升级突击队”。领导说:“你们年轻人学得快,Spring Cloud 搞起来。” 我心里一万个MMP:我上一份工作连 Redis 都没碰过!
但没办法,为了年终奖,也为了不被裁(笑),我只能硬着头皮上。这篇博客就是我在踩了无数坑之后,总结出的一套“保命指南”。
别再用 Python 写业务逻辑了(认真脸)
我知道很多同学和我一样,是从 Python 转 Java 后端的。Python 写爬虫是真的爽,requests + BeautifulSoup + pandas,十分钟搞定一个数据采集任务。但一旦涉及到高并发、分布式事务、服务治理这些,Python 的生态就有点捉襟见肘了。
我们之前有个 Python 微服务,部署在 Kubernetes 上,结果每次大促都 OOM,运维兄弟差点把我拉黑。后来换成 Java + Spring Cloud,内存稳如老狗,QPS 直接翻了三倍。
所以如果你也在纠结语言选型——业务系统,请用 Java;爬虫/脚本/数据分析,请继续用 Python。别硬刚,真的。
第一步:注册中心选型,Nacos 还是 Eureka?
Spring Cloud 官方推荐 Eureka,但国内公司基本都用 Nacos。为啥?因为 Nacos 支持配置中心 + 服务发现一体化,还能看可视化界面,运维大哥看了都说好。
我一开始傻乎乎地用了 Eureka,结果发现它不支持动态配置刷新,改个超时时间都要重启服务。被测试同事追着问:“你这服务怎么又挂了?” 我只能苦笑:“在演《重启人生》。”
换成 Nacos 后,世界清净了。启动命令一行搞定:
# 启动 Nacos(单机模式)
sh startup.sh -m standalone
然后在 application.yml 里加几行配置:
spring:
application:
name: order-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
config:
server-addr: localhost:8848
file-extension: yaml
注意:
spring.application.name必须全局唯一!我第一次把user-service和order-service都写成service,结果两个服务互相调用自己,死循环了,CPU 直接 100%,线上差点事故。
服务间调用:Feign 还是 RestTemplate?
早期我用 RestTemplate 手动拼 URL,代码丑得像我写的 Python 爬虫初稿:
String url = "http://user-service/api/v1/users/" + userId;
User user = restTemplate.getForObject(url, User.class);
问题来了:万一 user-service 挂了怎么办?重试?超时?熔断?全得自己写。
后来改用 OpenFeign,配合 Ribbon(虽然现在官方推荐 LoadBalancer,但 Feign 默认集成 Ribbon 更省事),直接声明式调用:
@FeignClient(name = "user-service")
public interface UserServiceClient {
@GetMapping("/api/v1/users/{id}")
User getUserById(@PathVariable("id") Long id);
}
再加个熔断降级(用 Resilience4j 或 Sentinel):
@FeignClient(name = "user-service", fallback = UserServiceFallback.class)
public interface UserServiceClient { ... }
这样,就算 user-service 挂了,也能返回兜底数据,不至于整个链路雪崩。
最坑的坑:跨服务事务
我们有个下单流程:创建订单 → 扣减库存 → 发送消息。三个服务,三个数据库。
我天真地以为用 @Transactional 就行了,结果测试一跑,库存扣了,订单没建成功——分布式事务没处理!
Spring Cloud 本身不解决分布式事务,得靠其他方案:
| 方案 | 适用场景 | 学习成本 | 可靠性 |
|---|---|---|---|
| Seata AT 模式 | 强一致性要求 | 中 | 高 |
| RocketMQ 事务消息 | 最终一致性 | 低 | 中高 |
| TCC | 高性能场景 | 高 | 极高 |
我们选了 RocketMQ 事务消息,因为团队已经有 MQ 基础设施,而且最终一致性对我们够用。代码大概是这样:
// 1. 发送半消息
TransactionMQProducer producer = new TransactionMQProducer("order_tx_group");
producer.sendMessageInTransaction(message, null);
// 2. 执行本地事务(创建订单)
// 3. 根据结果 commit / rollback
虽然比单体复杂,但至少不会出现“钱扣了,货没发”的史诗级 Bug。
配置管理:别再 hardcode 了!
以前我写 Python 爬虫,经常把 API Key 写死在代码里,被 Git 提交后又被安全扫描工具告警,尴尬到脚趾抠地。
在微服务里,所有配置必须外置。Nacos 配置中心完美解决这个问题。
比如数据库连接:
# 在 Nacos 控制台创建 dataId: order-service.yaml
spring:
datasource:
url: jdbc:mysql://prod-db:3306/order?useSSL=false
username: prod_user
password: ${DB_PASSWORD} # 从环境变量读取,更安全
这样,开发、测试、生产环境一套代码,三套配置,再也不用改代码重新打包。
性能与监控:没有监控的微服务等于裸奔
上线第一天,QPS 到 500,系统就慢得像树懒。查了半天,发现是 Feign 调用没设超时:
feign:
client:
config:
default:
connectTimeout: 2000
readTimeout: 5000
另外,一定要集成 Micrometer + Prometheus + Grafana,不然你根本不知道哪个服务拖了后腿。
我们还加了 Sleuth + Zipkin 做链路追踪。有一次用户投诉“下单慢”,我直接在 Zipkin 里看到是 inventory-service 的 SQL 没走索引,三分钟定位问题,运维都惊了:“你咋知道的?”
总结:微服务不是银弹,但值得折腾
现在回头看,Spring Cloud 入门其实不难,难的是理解分布式系统的思维:网络会断、服务会挂、数据会不一致。
而工具方面,我试过 GitHub Copilot、CodeWhisperer,甚至通义灵码,但最后还是回归 Cursor——它不仅能理解整个项目上下文,还能根据我的注释自动生成 Feign Client 或 Nacos 配置,效率提升至少 30%。尤其是在深夜加班 debug 时,一句“帮我生成一个带熔断的 Feign 调用”简直救命。
如果你也在从单体走向微服务,记住三点:
- 先小步拆分:别一上来就全拆,先拆一个非核心服务试水。
- 监控先行:没有可观测性,微服务就是黑盒炸弹。
- 别怕犯错:我现在的简历里,大概有 70% 的经验来自“当时搞砸了,后来怎么修好的”。
最后,祝大家都能顺利度过微服务入门期,少加班,多涨薪。
(以及,产品经理们,求求你们别再在周五提需求了……)

评论 0