从零开始搭建 Spring Cloud 微服务:一个实战者的血泪经历分享
开篇背景:为什么我会走上微服务这条路?

去年我所在的团队接到了一个新项目——为公司打造一套面向全国用户的会员管理系统。初期我们考虑用单体架构,因为开发速度快、结构简单,适合快速验证。但没过多久,产品负责人就告诉我们:“这不是个简单的后台系统,要支持高并发,还要能对接多个外部系统,未来可能会有十几条业务线同时接入。”
听到这句话的时候,我就知道这绝不是传统单体架构能轻松承载的。
于是我们决定转向微服务架构,使用 Spring Cloud 这一当时在社区和企业中都相对成熟的技术栈。刚开始大家都很兴奋,以为有了 Spring Boot + Spring Cloud,就能轻松构建出可伸缩、模块清晰的系统。结果没想到的是,从头搭建一个稳定可用的微服务架构,远比想象中复杂得多。
这篇文章,我希望结合我在实际项目中的经验,带着你一起走一遍“从零到一”的 Spring Cloud 微服务搭建之路,不讲太多概念堆砌,直接上干货。
遇到了哪些问题?微服务并非银弹

我们在项目初期就踩了不少坑,最开始是服务拆分不当导致接口混乱,之后是注册中心和服务发现配置错误,最后甚至连日志追踪都成了难题。
主要挑战:
服务拆分不清晰
- 初期为了赶进度,把用户管理、订单管理、权限系统等统统作为独立服务部署。
- 结果服务之间频繁调用,调用链变长,接口边界混乱,维护成本陡增。
注册中心选型失误
- 最初选择的是 Eureka,但后来发现它在大规模服务下性能表现一般,尤其是在高峰期频繁报错。
- 后来改用了 Nacos,才真正实现服务自动注册与健康检查。
调用链追踪缺失
- 多服务并行时,一个问题可能涉及 5~6 个服务的日志输出。
- 没有统一的 Trace ID,排查效率极低,一度影响上线进度。
数据库设计混乱
- 有些表没有明确归属某个服务,多个服务共用一张表。
- 导致事务难以控制,数据一致性堪忧,甚至出现过脏数据。
这些问题让我深刻意识到:微服务不是随便拆几个模块就能解决的事,它是一整套系统性工程,需要提前规划、合理分工和持续迭代的能力。
解决方案:Spring Cloud 实战架构设计
技术选型回顾:
- Spring Boot 2.7:用于基础服务框架
- Spring Cloud 2021.0.x:支撑微服务核心组件
- Nacos 2.x:服务注册发现+配置中心
- OpenFeign + LoadBalancer:声明式 REST 客户端
- Spring Gateway:API 网关
- Sentinel 1.8+:限流熔断
- SkyWalking(Apache):分布式链路追踪
- MySQL 8.0 + MyBatis Plus:数据库层
整体架构图简述(文字版):
[客户端] → [Spring Gateway API网关]
↓
[Nacos Server]
↗ ↘ ↘ ↘
[认证服务][用户服务][支付服务][商品服务]...
↘ ↘ ↘
[MySQL集群] [Redis缓存] [SkyWalking Agent]
核心流程:
- 客户端请求首先到达网关
- 网关根据路由规则转发给具体微服务
- 每个服务启动时向 Nacos 注册自身信息
- 其他服务通过 Feign 调用完成协作
- 所有调用链路由 SkyWalking 自动采集
- Sentinel 负责流量控制和异常熔断
代码实践:从零搭建一个微服务项目
接下来我们以“用户服务”为例,带大家看看如何一步步搭建微服务的基础结构。
第一步:初始化 Spring Boot 工程
使用 start.spring.io 创建基本项目模板,添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
第二步:开启 Nacos 服务注册
application.yml 配置示例:
server:
port: 8081
spring:
application:
name: user-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
management:
endpoints:
web:
exposure:
include: "*"
主类加上注解激活服务注册与 Feign 客户端:
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
第三步:Feign 接口远程调用
比如我们要在用户服务中调用订单服务:
定义 Feign 客户端:
@FeignClient(name = "order-service")
public interface OrderClient {
@GetMapping("/orders/{userId}")
List<OrderDTO> getOrdersByUserId(@PathVariable String userId);
}
注入后直接使用即可:
@RestController
@RequestMapping("/users")
public class UserController {
private final OrderClient orderClient;
public UserController(OrderClient orderClient) {
this.orderClient = orderClient;
}
@GetMapping("/{id}/orders")
public List<OrderDTO> getUserOrders(@PathVariable String id) {
return orderClient.getOrdersByUserId(id);
}
}
这个过程中你会遇到负载均衡的问题,确保 LoadBalancer 组件引入无误,否则会抛出找不到目标地址的异常。
踩坑记录:那些年我掉过的坑
坑点一:Feign 不兼容 WebFlux?
我们初期尝试使用 Spring WebFlux 提升吞吐量,但很快发现 WebFlux 和 Feign 存在兼容性问题,特别是响应类型如果是 Mono 或 Flux 的话,会导致编译失败或运行时异常。
解决方案:
- 放弃 WebFlux,专注同步编程模型。
- 若坚持要用异步响应,需自定义 Feign 解码器或切换到 WebClient 方案。
坑点二:Nacos 自动下线机制太敏感
某次测试环境突发网络抖动,服务瞬间被标记为宕机,触发大量降级逻辑,导致部分功能不可用。
解决方案: 调整 Nacos 客户端的心跳间隔和超时设置,在服务端也修改对应参数:
spring:
cloud:
nacos:
discovery:
heartbeat-interval: 5000 # 心跳间隔
fail-fast: false # 不强制快速失败
也可以通过 sentinel 设置调用失败率阈值进行优雅处理。
坑点三:Trace ID 丢失
在网关和内部服务之间传递 Trace ID 时出现了断裂,导致 SkyWalking 无法串联完整链路。
解决方案:
使用 requestHeader + ThreadLocal 的方式手动传递 traceId,并利用 Spring 的 Filter 实现上下文绑定。
架构优化:不只是搭建,更要可持续发展
微服务不是搭起来就行,后续还要考虑很多生产上的问题,比如:
数据库设计原则:
- 每个服务独占自己的 DB Schema(或 Table Group),避免跨服务共享表。
- 对于频繁查询的数据可以做“反范式化”,如用户服务缓存常用订单字段。
- 使用 ShardingSphere 分库分表(如有大数据增长预期)。
接口设计建议:
- 设计统一的 API 返回结构体,例如:
public class Result<T> {
private int code;
private String message;
private T data;
// getters/setters
}
- 尽量避免深层嵌套,保持接口语义清晰简洁。
生产运维经验:
- 服务打包尽量使用 Docker,便于版本管理和快速发布。
- 监控方面一定要配合 Prometheus + Grafana,实时查看 QPS、耗时、错误率。
- 日常压测工具建议使用 JMeter + SkyWalking,观察调用链是否完整、是否存在瓶颈。
成果与收益总结
经过 3 个月的重构和打磨,我们的系统最终实现了以下几个关键指标:
| 指标 | 旧系统 | 新系统 |
|---|---|---|
| 单节点并发上限 | ~2k QPS | ~10k QPS |
| 平均接口响应时间 | 120ms | 50ms(核心接口) |
| 日志可追溯性 | 弱 | 强(基于 SkyWalking) |
| 模块耦合度 | 高 | 低 |
更关键的是,随着业务扩展,我们可以快速新增订单、积分、优惠券等多个独立服务,而不会对已有系统造成太大冲击。
给读者的一些建议
如果你打算或正在搭建 Spring Cloud 微服务系统,以下是几点来自一线实战的建议:
别一开始就追求“高大上”
- 先确定核心业务领域再拆服务。
- 初期可以只拆两三个核心模块,不要贪多。
技术选型要慎重
- Spring Cloud Alibaba 是目前国产生态适配最好的组合之一。
- 如果你不需要阿里云生态支持,可以选择 Consul/Eureka/Consul UI 搭配。
监控体系尽早介入
- 越早集成 APM 越省力,不然后期定位问题非常痛苦。
- SkyWalking、Pinpoint、Zipkin 都是不错的选型方向。
别忽视服务治理
- 服务间调用、降级、限流这些不能等出问题才考虑。
- 利用好 Sentinel、Resilience4j 等开源库可以事半功倍。
文档和规范要有
- 接口文档、服务清单、职责划分最好形成统一文档。
- 否则团队多了以后谁都搞不清哪个服务干什么。
结语:写在最后的一点感悟
回想整个项目过程,我常常觉得微服务就像一场马拉松,比谁跑得快更重要的是谁能稳稳地跑到终点。Spring Cloud 提供了一套成熟的工具链,但它只是工具,真正的成功还是靠团队的协同、良好的架构设计和持续改进的决心。
如果你刚起步,别怕慢;如果你已经在路上,记得定期回望,不断优化。
愿你在微服务的路上走得稳健,少踩坑。欢迎留言交流你的实践经验,我们一起成长!
作者:李明(化名),一名深耕后端多年的开发者,经历过无数个加班日夜,也在一次次项目重构中沉淀了宝贵的经验。

评论 0