Spring Cloud 从零开始:一位全栈工程师的实战入门手记
引言

大家好,我是李航,一名有着多年后端开发经验的全栈开发者。今天我想跟你聊聊我去年接手的一个项目——一个典型的单体应用向微服务架构转型的故事。这个过程中,我们选择了 Spring Cloud 作为技术栈核心。
这篇文章将结合我亲身参与的项目经历,详细讲述我如何一步步搭建起基于 Spring Cloud 的微服务架构体系,期间踩过的坑、解决的问题、获得的经验教训,以及最终的成果。
希望这篇文能帮你少走弯路,顺利开启你的微服务之旅。
背景与挑战:为什么选择微服务?

我们当时的系统是一个典型的单体架构应用,后台是 Spring Boot + MySQL,前端 Vue,运行在一台服务器上。业务模块集中在用户管理、订单处理、库存管理几块,功能虽不算复杂,但因为耦合度高,每次上线都像打仗一样。
面临的主要问题包括:
- 部署难:整个项目打包成一个 jar 文件,修改一处就要重新部署。
- 扩展性差:当某个模块(例如订单)并发突增时,整套系统都得扩容。
- 维护困难:代码量超过 30w 行,新人入职成本极高。
- 稳定性受影响:一个模块出现 bug 或内存溢出,可能会影响整个系统。
我们迫切需要一种更灵活、可扩展、易维护的架构方式 —— 所以,我们决定尝试微服务化。
技术选型:为什么选择 Spring Cloud?
我们团队当时熟悉 Java 技术栈,且已有 Spring Boot 的项目基础,所以很自然地选择了 Spring Cloud 来构建我们的微服务体系。
最终的技术架构图大致如下:
[外部请求]
↓
[Nginx]
↓
[网关 Gateway]
↓
[服务注册中心 Eureka]
↓
[用户服务] [订单服务] [库存服务] [支付服务]
↓
[数据库]
这套架构中,我们采用了以下组件:
| 模块 | 技术选型 |
|---|---|
| 注册中心 | Eureka |
| 网关 | Gateway |
| 负载均衡 | Ribbon |
| 配置中心 | Config Server |
| 熔断器 | Hystrix(后续替换为 Resilience4j) |
| 分布式链路追踪 | Sleuth + Zipkin |
| 消息队列 | RabbitMQ(部分异步解耦) |
入门第一步:搭建注册中心 Eureka
首先,我选择搭建一个最简单的注册中心:Eureka Server。
创建步骤非常简单:
- 新建一个 Spring Boot 项目
- 添加
spring-cloud-starter-netflix-eureka-server依赖 - 在
application.yml中配置 Eureka Server 基本参数 - 启动类添加
@EnableEurekaServer注解
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
启动之后访问 http://localhost:8761/ 即可看到 Eureka 控制台页面。
⚠️ 小贴士:早期版本 Eureka 对健康检查比较严格,默认会强制每隔一段时间拉取注册信息。如果你本地开发网络不稳定,很容易被标记为 DOWN,可以临时关闭健康检查:
eureka: instance: preferIpAddress: true health-check-url-path: /actuator/health
第二步:创建第一个微服务 —— 用户服务
接下来就是创建我们的第一个微服务模块:user-service。
- 创建一个新的 Spring Boot 工程
- 添加
spring-cloud-starter-netflix-eureka-client依赖 - 添加
spring-boot-starter-data-jpa(数据库交互) - 配置
application.yml注册到 Eureka - 实现接口逻辑
关键配置如下:
spring:
application:
name: user-service
server:
port: 8081
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
management:
endpoints:
web:
exposure:
include: "*"
主类加上 @EnableDiscoveryClient 注解即可完成注册到 Eureka。
这里有个小插曲:一开始我在测试注册时发现服务没有正常上报实例地址,后来发现是因为主机名解析不对。后来统一加上了
preferIpAddress: true,让 Eureka 使用 IP 地址而不是主机名。
第三步:建立统一入口 —— Gateway 网关
有了多个服务后,我们需要一个统一的 API 入口,于是引入了 Spring Cloud Gateway。
它的作用是:
- 统一处理请求路由
- 提供限流、认证、日志等功能的基础能力
- 解耦客户端和服务端
网关本身也是一个 Spring Boot 应用,只需添加依赖并配置路由规则。
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/user/**
其中 lb:// 表示负载均衡,会自动查找名为 user-service 的所有可用实例。
💡 Tips:Spring Cloud Gateway 支持很多高级功能,比如自定义过滤器实现鉴权、限流等。我们后来也写了一个 JWT 鉴权的全局过滤器,感兴趣的话我可以专门写一篇分享。
代码实践:微服务间调用怎么做?
微服务之间免不了要互相调用。我们在最开始阶段使用的是 Feign + Ribbon:
@FeignClient(name = "order-service")
public interface OrderServiceClient {
@GetMapping("/orders/{userId}")
List<Order> getOrdersByUserId(@PathVariable String userId);
}
但后来发现 Feign 有些限制,并且官方已经不推荐使用。所以我们在新项目中改用 OpenFeign + LoadBalancer 的方式。
另外我们还在逐步过渡到使用 RestTemplate + @LoadBalanced 的形式:
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
// 使用示例
response = restTemplate.getForObject("http://order-service/orders/" + userId, Order[].class);
虽然现在也有 WebFlux/WebClient 可选,但在实际生产中,还是以简单稳定为主。
踩坑经验总结:那些年我们一起掉进去的“坑”
✅ 坑 1:Feign 默认不支持 POST 请求 Body 传递对象
刚开始调用其他服务时,我们用 Feign 发送 POST 请求总是报错,后来查文档才发现 Feign 默认只支持 GET 和 Query 参数传递。要传递对象,必须加注解:
@PostMapping("/create")
ResponseEntity<?> createOrder(@RequestBody OrderDTO orderDTO);
同时要在 Feign 客户端添加 @RequestLine 注解或开启 feign.formatter.disabled=false。
✅ 坑 2:Hystrix 熔断机制设置不合理导致服务雪崩
我们早期用了 Hystrix 做熔断降级,但由于阈值设置太低,在高峰期频繁触发熔断,反而导致用户体验变差。
后来换成了 Resilience4j,配置更灵活,且不依赖线程池资源。
✅ 坑 3:Eureka Client 自愈失败
有时候服务挂掉,Eureka 并不会立即清除下线的服务实例,导致调用方继续去请求已死亡的节点。这时候可以通过设置健康检查和 Eureka 心跳策略来缓解。
eureka:
instance:
health-check-url-path: /actuator/health
client:
healthcheck:
enabled: true
项目效果与收益
经过两个月的努力,我们完成了整个系统的微服务拆分:
- 核心模块分别独立部署
- 使用 Docker 容器编排(Kubernetes 正在推进中)
- 所有服务通过 Gateway 统一接入
- 实现了基本的日志收集、链路追踪、监控告警
迁移完成后,上线效率提高 50%以上,紧急回滚速度明显加快,排查问题也能快速定位。
更重要的是,开发人员分工更清晰,新人上手难度大大降低。
我的一些心得体会
不要一开始就追求“完美”架构
很多同学刚接触 Spring Cloud 时总想一步到位搭出完整的微服务生态,结果反被各种组件搞得晕头转向。建议先跑起来再说,边跑边优化。重视配置管理和环境隔离
开发、测试、预发布、生产环境配置不同,别忘了使用Config Server来统一管理配置文件,否则到了上线时就容易出大乱子。链路追踪是标配
一定要尽早接入 Sleuth + Zipkin,哪怕只是日志打标也可以。不然线上问题根本无法追溯,微服务越多越头痛。数据库设计也要松耦合
不要为了偷懒搞共享数据库,那样违背了微服务的核心理念。每个服务应该有自己独立的数据库,表结构变更互不影响。微服务不是银弹
如果你的系统不大,或者业务变动频繁,微服务反而会增加复杂度。一定要根据实际情况权衡。
写在最后
回头来看,微服务这条路并不轻松,但我们成功迈出了第一步。Spring Cloud 虽然强大,但也有很多坑等着你去踩。
作为过来人,我只想说一句:别怕试错,多看文档,多动手,早踩坑比晚踩好。
如果你正在学习微服务,欢迎留言交流,我会尽量帮忙解答;如果文章对你有帮助,也请点个赞鼓励一下,这对我写作是非常大的动力!
未来我也计划出一系列关于微服务进阶的文章,比如:
- Spring Cloud Alibaba 实战
- Kubernetes + Helm 部署实战
- 微服务权限设计(OAuth2 & JWT)
有兴趣的同学记得关注我。
📅 作者:李航(资深全栈开发工程师)
🛠 GitHub:github.com/lihangdev
📬 Email:lihang.code@gmail.com

评论 0