Spring Cloud从零开始:微服务入门指南
作者:一个在上海浦东合租屋里敲代码的自由开发者
写于2024年6月的一个雨夜,窗外是陆家嘴闪烁的霓虹,屋里是女朋友在追《庆余年2》的背景音
去年十月,我还在一家传统制造业做后端开发,月薪15k,朝九晚六,生活安稳得像一杯温开水。但心里总有一股说不清的焦虑——项目还是单体架构,技术栈停留在Spring Boot 2.3,连Docker都只是“听说过”。每次刷脉脉,看到同行晒offer:“Spring Cloud + Kubernetes + 阿里云,22k起步”,我就坐立不安。
那天晚上和女朋友小雅吃饭,她夹了块红烧排骨给我,突然问:“你最近是不是有心事?代码又跑崩了?”
我苦笑:“不是代码崩了,是我快崩了。感觉自己快被时代甩下车了。”
她放下筷子,认真看着我:“要不……试试转型?你不是一直说想搞微服务吗?”
一句话点醒了我。第二天,我递交了辞职信,决定用三个月时间,从零开始攻克Spring Cloud。自由职业的第一站,就从这个微服务入门项目开始。
为什么是Spring Cloud?而不是Python?
先说清楚,我本科学的是计算机,工作后主要用Java,但私下其实很喜欢Python——简洁、灵活,写脚本、爬虫、数据分析都顺手。去年接了个私活,帮一家跨境电商做数据清洗,全用Python搞定,三天赚了4000块。所以很多人问我:“既然喜欢Python,为什么不转Go或者直接用FastAPI搞微服务?”
我的回答是:现实考量。
在国内企业级开发领域,Java生态依然占据绝对主导地位。尤其是金融、电商、政务系统,Spring全家桶几乎是标配。而Spring Cloud,正是构建Java微服务的标准答案。虽然Python也有Tornado、Sanic甚至Dapr支持微服务,但生态碎片化严重,生产环境案例少,社区支持弱。作为一个要靠技术吃饭的自由开发者,我不能只凭喜好选技术栈——得看市场要什么。
而且,说实话,微服务的核心思想是通用的。无论是用Spring Cloud还是Python框架,服务注册发现、配置中心、熔断限流这些概念都是一样的。先用成熟的Java生态把路走通,回头再迁移到其他语言,反而更稳。
我的第一个微服务项目:模拟电商系统
我给自己定了个目标:用Spring Cloud搭建一个极简电商系统,包含用户服务、商品服务、订单服务三个模块,全部容器化部署,并接入基础治理能力。
Day 1:环境搭建,光依赖就折腾到凌晨两点
我在Mac上装好JDK 17、Maven、Docker、IntelliJ IDEA。然后新建项目,引入spring-cloud-starter-parent,版本选了2022.0.3(对应Spring Boot 3.1.x)。结果一运行,报错:
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContext
我懵了。后来才反应过来:Spring Boot 3.x全面转向Jakarta EE 9,包名从javax.*变成了jakarta.*。而我本地某些旧依赖还没升级。查了两小时Stack Overflow,终于搞定。
那晚小雅已经睡了,我坐在书桌前,窗外下着小雨,耳机里放着Lo-fi Hip Hop。心里嘀咕:“这还只是开始,后面还有多少坑?”
Day 3:Eureka服务注册与发现
我创建了user-service和product-service,并在eureka-server中注册。本地测试一切正常,两个服务互相调用毫无压力。但当我试图用RestTemplate从订单服务调用用户服务时,问题来了:
// 错误示范!
String url = "http://localhost:8081/user/" + userId;
User user = restTemplate.getForObject(url, User.class);
这种硬编码IP端口的方式,在微服务里就是自杀行为。正确的做法是:
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
// 调用时直接用服务名
String url = "http://user-service/user/" + userId;
加上@LoadBalanced注解后,Ribbon(或新版本的LoadBalancer)会自动从Eureka拉取服务列表并做负载均衡。那一刻,我仿佛打通了任督二脉——原来“服务发现”不是玄学,而是实实在在的代码协作。
Day 7:配置中心Nacos登场
以前改个数据库密码,得重新打包部署。现在,我把所有配置扔进Nacos,动态刷新。比如商品服务的价格策略,通过@RefreshScope注解,不用重启就能生效。
但第一次集成Nacos时,我又踩了坑:Spring Boot 3.x不兼容Nacos 1.x客户端。必须升级到Nacos 2.2+,还得手动排除旧版依赖。这种“版本地狱”,估计每个Java开发者都经历过。
小雅看我对着屏幕皱眉,递来一杯热咖啡:“又卡住了?”
我叹气:“Java生态太庞大了,好处是啥都有,坏处是啥都得配。”
她笑:“那你当初为啥不选Python?写个Flask,三行代码就起服务。”
我摇头:“Flask适合小而美,但扛不住高并发、高可用的企业场景。自由职业不是玩票,得对客户负责。”
微服务 ≠ 拆分就完事
很多人以为微服务就是把单体应用切成几个小服务,部署到不同机器上。大错特错!
我在模拟订单创建流程时,就遇到了典型的分布式事务问题:
- 创建订单 → 扣减库存 → 扣用户余额
如果第二步失败,前面的操作必须回滚。但在微服务里,没有全局事务。
我尝试了三种方案:
- 两阶段提交(2PC):性能差,不实用
- 消息队列+本地事务表:复杂,容易丢消息
- 最终一致性 + 补偿机制:最可行
最后我用RabbitMQ实现了“可靠消息最终一致性”:订单服务发消息到MQ,商品服务消费后扣库存,失败则重试;若长时间失败,触发补偿(比如人工介入)。虽然做不到强一致,但业务可接受。
这个过程让我明白:微服务的难点不在技术,而在业务建模和容错设计。技术只是工具,核心是理解你的系统如何在“不完美”的网络环境中稳定运行。
为什么我还保留Python?
尽管主攻Java微服务,我依然每天用Python处理辅助任务:
- 用
requests+BeautifulSoup抓取竞品价格,喂给商品服务做动态定价 - 用
pandas分析订单日志,生成周报 - 用
locust做压力测试,模拟高并发下单
上周五晚上,我还用Python写了个小工具:自动从Nacos导出配置,生成Markdown文档,方便客户查阅。100行代码,省了我两小时手工整理。
所以我的建议是:主语言深耕,副语言赋能。Java构建系统骨架,Python处理血肉细节。两者互补,效率翻倍。
自由职业后的变化
辞职三个月后,我接到了第一个Spring Cloud项目:帮一家生鲜电商重构订单系统。对方原本用PHP单体架构,高峰期经常超时。我用Spring Cloud Gateway做统一入口,Feign做服务调用,Sentinel做熔断,Redis缓存热点数据。上线后,TPS从300提升到1800,老板直接打了8万尾款。
现在我和小雅还是住在浦东张江,房租3500,但我的月收入稳定在22k以上。更重要的是,我不再焦虑了。因为我知道,只要持续学习,市场永远需要能解决问题的人。
给初学者的几点真心话
别一上来就追求“高大上”
先搞懂Eureka、Ribbon、Feign、Hystrix(或Resilience4j)这几个核心组件。Nacos、Sentinel、Gateway可以后续加。微服务不是堆砌技术,而是解决实际问题。动手!动手!动手!
看十篇教程不如自己写一行代码。哪怕只是让两个服务互相调用成功,那种成就感会推着你继续前进。善用Python做辅助
别把自己局限在Java世界。用Python写测试脚本、监控告警、数据迁移,效率飞起。接受“不完美”
微服务天生复杂。网络延迟、服务雪崩、配置漂移……这些都是常态。学会在混沌中建立秩序,才是真本事。
最后
写这篇文章时,已经是凌晨一点。小雅早就睡了,桌上还剩半杯冷掉的咖啡。我关掉IDEA,看了一眼银行卡余额——这个月又入账3万。不是炫耀,而是想告诉每一个正在挣扎的开发者:
技术不会辜负认真的人。
Spring Cloud很难吗?难。但拆解开来,不过是一堆可学习、可实践的模块。你不需要一开始就掌握全部,只需要比昨天的自己多懂一点点。
如果你也在上海,也在为技术焦虑,不妨今晚就打开IDE,新建一个eureka-server。也许三个月后,你也能笑着说出那句:“微服务?也就那样。”
共勉。
—— 一个在浦东出租屋里,一边写代码一边憧憬未来的自由开发者
2024年6月于上海

评论 0