Spring Cloud从零开始:微服务的实践之路
开篇:为什么选择Spring Cloud?

我是某家电商平台技术团队的一名负责人。两年前,我们公司正处于快速扩张期,单体架构的系统已经越来越难以支撑不断增长的业务量和并发请求。尤其是大促期间,系统经常出现卡顿、超时甚至崩溃的现象。
那会儿我们的应用是一个将近200万行代码的Java后端,部署在几台Tomcat服务器上,前端用的是Vue,数据库主要是MySQL + Redis。虽然整体结构还算清晰,但模块之间高度耦合,改动一个功能动辄需要测试整个项目,上线时间被拉得很长。
为了打破这种“牵一发而动全身”的局面,我们决定向微服务架构转型。调研之后,最终选用了Spring Cloud Alibaba作为核心技术栈,结合Nacos做服务注册与发现,加上Sentinel做流量控制,Seata处理分布式事务,以及Gateway来做API网关。
这篇文章,就是基于我们团队从零搭建微服务架构的实际经验写成的。我会尽可能多地用实际场景来说明问题、展示解决方案,并分享我们在实践中踩过的坑和总结的经验教训。
问题描述:微服务不是银弹,但也确实解决了关键痛点

微服务并不是适用于所有项目的万能方案,但在我们当时的背景下,它是最佳选择之一。那么具体来说,我们遇到了哪些问题呢?
1. 模块耦合严重,维护成本高
原本的系统里订单、商品、库存等模块都混在一个工程中,每次修改都要全量打包、部署。一个模块出错可能影响其他模块的功能,尤其在频繁迭代的情况下,开发效率极其低下。
2. 高并发支撑能力弱
大促期间QPS峰值能达到上万,但因为是单体架构,扩容只能通过加Tomcat实例,无法做到对某些热点模块单独扩容。
3. 灰度发布与AB测试困难
没有统一的服务治理机制,想做灰度发布、路由规则调整等操作非常麻烦,必须靠手动配置或改代码来实现。
这些问题归根结底都指向了一个核心诉求:解耦、自治、可控。
解决方案:Spring Cloud全家桶实战落地

确定了要引入微服务架构后,我们制定了分阶段的实施计划:
- 第一阶段:完成服务拆分、注册中心搭建;
- 第二阶段:打通服务通信链路,引入熔断限流;
- 第三阶段:完善日志监控、持续集成、安全认证等配套设施;
- 第四阶段:实现自动化部署与弹性伸缩。
接下来我会以我们最典型的三个服务为例,讲述我们的设计思路和关键技术实现细节:
服务拆分:订单服务、商品服务、用户服务
初始拆分策略
我们将原有系统的模块按领域拆分,每个模块作为一个独立的Spring Boot服务,各自拥有独立的数据库(当然有些表是共用的,比如用户信息)。
最初我们遇到的问题是:
怎么定义一个“合理”的服务边界?
举个例子,商品详情页包含价格、库存、评论、推荐信息等多个字段。这些信息来自不同的模块。如果全部调用远程服务,会不会导致接口响应变慢?
我们尝试了几种方式:
- 本地缓存+异步更新:使用Redis做商品基本信息的缓存,每个小时从商品服务同步一次数据;
- 聚合服务层:新建一个叫
product-view的服务,专门负责组合多个子服务的数据; - 跨服务查询优化:允许部分非实时敏感字段走冗余表或Elasticsearch,提高访问性能。
最后我们选择了第二种聚合服务层方案,虽然增加了服务数量,但从长期可维护性来看,是值得的。
数据库设计上的取舍
服务拆分之后,数据库也自然分离。但这也带来了一些问题,例如:
- 用户订单中的商品信息应该保存快照,避免商品信息变更后订单展示异常;
- 库存扣减逻辑如何保证一致性?我们初期采用的是定时任务+人工补偿,后来接入了Seata做分布式事务管理。
关于接口设计,我们也做了一些约定:
- 所有服务对外提供RESTful API,遵循标准返回格式;
- 增加版本号支持多版本兼容,如
/v1/product/detail; - 所有请求必须携带traceId,便于链路追踪。
技术选型与实现
使用Nacos做服务注册与发现
Spring Cloud原生推荐的是Eureka,但我们团队更倾向于国产生态,而且后续要用到Alibaba全家桶,所以直接选择了Nacos。
部署Nacos Server时我们一开始用的是单机模式,结果压测的时候发现注册列表读写压力很大,特别是在服务重启频繁的情况下,会导致集群状态不稳定。后来改成集群模式 + MySQL持久化存储,才解决了这个问题。
配置中心也是一样,我们之前所有的配置都是放在各个项目的application.yml文件中。服务多了以后,配置管理变得极为复杂。
所以我们把通用配置项都放到Nacos配置中心,比如:
spring:
datasource:
url: jdbc:mysql://...
username: ...
password: ...
服务启动时只需要指定namespace和group即可加载对应环境的配置。
服务间通信:RestTemplate还是Feign?
早期我们用的是Spring自带的RestTemplate,但随着服务增多,代码冗余明显,而且参数传递、错误处理都需要自己封装。
于是我们切换到了Feign,配合Ribbon实现了客户端负载均衡,并且用OpenFeign做了接口声明式调用,效果很好。
这里有一个真实踩坑案例:有一次某个服务调用一直失败,但日志显示连接正常。排查后才发现,原来Feign默认不启用Hystrix降级(即使你引入了相关依赖),需要手动开启熔断。
解决办法是在配置中添加:
feign:
hystrix:
enabled: true
然后为每个Feign Client编写fallback类,实现容错处理。
流量控制 & 安全防护:Sentinel + Gateway
随着服务越来越多,我们意识到流量控制和权限校验的重要性。
我们用了Spring Cloud Gateway作为统一入口,做了如下事情:
- 请求路由:根据路径将请求转发到对应的下游服务;
- 权限验证:对接JWT Token,拦截非法请求;
- 请求限流:使用Sentinel为关键接口设置TPS限制;
- 黑白名单:支持根据IP做临时封禁。
说到Sentinel,它真的是一个非常好用的组件。我们通过仪表盘可以实时看到接口的QPS、响应时间、线程数等指标,还可以在线调整限流规则。
不过需要注意一点:Sentinel默认只记录最近60秒内的数据,如果你要做更长时间的趋势分析,最好配合Prometheus + Grafana。
分布式事务:Seata的抉择与实践
当订单服务和库存服务需要同时修改数据的时候,事务一致性就成了头号难题。
最初我们用的是“伪事务”——即先扣库存再建订单,失败就回滚库存。这个方法简单但容易丢数据,尤其是在网络波动或超时情况下。
后来我们引入了Seata,采用AT模式进行全局事务协调。整体流程大致如下:
- 订单服务发起下单请求;
- 底层Seata生成XID,开启全局事务;
- 分别调用库存服务、优惠券服务等,执行本地SQL;
- 如果其中一个服务失败,Seata自动回滚所有分支事务;
- 提交成功则标记事务完成。
使用过程中我们发现几个需要注意的地方:
- 必须给所有涉及的数据库建立undo_log表;
- SQL不能使用批量插入(会被Seata识别为不支持);
- 表主键必须明确,不能使用UUID等不可逆字段;
- 一定要配合重试机制,避免因网络抖动造成误判。
这套机制在我们的系统中运行稳定,特别是在大促期间发挥了重要作用。
效果总结:微服务带来的改变和收益
微服务架构改造完成后,我们得到了以下几点显著提升:
| 指标 | 改造前 | 改造后 |
|---|---|---|
| 接口响应时间 | 平均400ms | 平均200ms |
| 上线频率 | 两周一次 | 每周多次 |
| 部署效率 | 全量部署 | 按服务灰度发布 |
| 异常定位耗时 | 小时级 | 分钟级 |
| 大促稳定性 | 多次崩盘 | 零故障 |
除了性能提升外,还有一个重要的“软实力”提升:团队协作更加高效。
以前一个改动往往牵涉多人配合,现在大家可以专注于各自负责的服务,只要接口文档明确,就能并行开发、快速上线。此外,我们还建立了统一的监控告警体系,大大提升了运维效率。
经验分享:给刚入门同学的建议
如果你也正准备踏上微服务这条路,下面这些经验希望对你有帮助:
1. 服务边界的设计比你想得更重要
不要一开始就把服务拆得太细,那样反而会造成过度设计。建议先从业务领域出发,按DDD的方式划分上下文边界。后期可以根据实际发展情况灵活调整。
小技巧:先搭一个骨架服务,跑通基础链路,再逐步细化。
2. 不要忽视服务治理基础设施
服务注册、配置中心、限流熔断、链路追踪……这些看似辅助的东西,才是微服务稳定运行的关键。否则你会发现:
“我明明把服务拆开了,为什么更难管理了?”
推荐使用:
- Nacos:集服务注册+配置中心于一体,开箱即用;
- Sentinel:限流、降级、熔断一站式搞定;
- SkyWalking / Zipkin:做链路追踪;
- Prometheus + Grafana:做指标采集和可视化。
3. 微服务不等于无限扩容
很多人以为微服务就可以随意扩容,实际上:
- 真正能扩容的是无状态的服务;
- 有状态的服务(如数据库、缓存)扩容仍然受限;
- 即使是Kubernetes也难以解决网络延迟和IO瓶颈问题。
建议在设计之初就要考虑横向扩展的能力边界。
4. 搞清“分布式事务”的本质
分布式事务不是用来解决一切问题的魔法药,它只是权衡之后的折中方案。我们最终也没有完全依赖Seata,而是根据场景分别采用了:
- 本地消息表;
- TCC补偿事务;
- Saga模式;
不同场景选择不同的方案才是王道。
5. 要有“DevOps”意识
服务拆分越多,越考验你的自动化能力。我们目前做到:
- Jenkins流水线自动构建镜像;
- GitLab Webhook触发部署脚本;
- Kubernetes滚动升级 + 健康检查;
- Prometheus告警 + 钉钉通知;
- ELK集中日志分析。
这些东西哪怕一开始做不完,也要有一个清晰的演进路线图。
结语:微服务是一条值得走下去的路
微服务从来不是一个简单的技术选型题,而是一个涉及架构、协作、运维、安全等多方考量的系统工程。刚开始的时候我们也会焦虑、迷茫,甚至怀疑是否真的有必要做这么大的重构。
但当我们真正走过这趟旅程之后,回头看:
是的,这条路并不轻松,但它让我们的系统更具生命力,也让团队更有战斗力。
如果你正在考虑是否要迈出这一步,请相信:
不是所有系统都适合微服务,但当你不得不面对快速增长和复杂演化的挑战时,微服务也许就是你手中那个不可或缺的工具。
愿你在探索的路上少走弯路,多些收获。
文章作者:张浩 | 某电商公司后端技术负责人
联系方式:zhanghao@example.com
个人博客:https://zhblog.tech
欢迎交流技术、架构、团队管理等相关话题

评论 0