从 Spring Boot 到 Spring Cloud:一个后端开发者的微服务实战之路
背景介绍:为什么要用 Spring Cloud?

几年前,我所在的公司还是一家使用单体架构的中小型电商平台。随着业务快速发展,系统开始变得臃肿,部署效率低、维护成本高、团队协作难等问题逐渐显现出来。当时我们尝试过模块化拆分,但收效甚微。
后来,在一次技术分享会上,我第一次接触到“微服务”这个词,特别是看到 Spring Cloud 在分布式系统中提供的服务治理能力时,内心有种“终于找到解药”的感觉。于是我们决定,把老项目迁移到微服务架构上来,而 Spring Cloud 成为了我们的首选工具链。
这篇文章将结合我当时参与的一个完整转型项目,带大家一步步了解如何从零开始搭建一个基于 Spring Cloud 的微服务架构体系。
我们遇到了哪些问题?

当时系统的主要痛点有:
- 代码库庞大:前后端混合在一个工程里,核心功能如订单、用户、商品都耦合严重,修改一处可能引发全站故障。
- 部署困难:每次上线都要全量发布,动辄十几分钟,影响用户体验。
- 扩展性差:高峰期服务器扛不住流量压力,无法快速横向扩展。
- 开发协同难:不同小组修改同一个项目容易冲突,版本控制复杂。
这些问题最终导致交付周期越来越长,运维成本居高不下。我们必须做出改变。
技术选型与整体架构设计

我们选择了 Spring Cloud 全家桶来作为微服务框架的基础,因为:
- 它与 Spring Boot 天然兼容,上手门槛低;
- 提供了丰富的开箱即用组件(服务注册发现、负载均衡、配置中心等);
- 社区活跃,文档丰富,遇到问题能找到答案。
架构图简述
整个微服务系统大概分为以下几个部分:
[ Gateway ]
|
|-----> [User Service]
|
|-----> [Product Service]
|
|-----> [Order Service]
|
|-----> [Config Server]
|
|-----> [Service Registry (Eureka)]
其中各组件的作用如下:
| 模块 | 功能描述 |
|---|---|
| Eureka | 服务注册与发现 |
| Zuul / Gateway | 请求路由,鉴权,限流 |
| Config Server | 集中管理各个服务的配置 |
| Hystrix | 服务熔断,防止雪崩 |
| Sleuth & Zipkin | 分布式日志追踪 |

接下来我会以其中一个子系统为例(比如订单服务),逐步展开具体的实现过程和关键代码。
代码实践:Spring Cloud 微服务搭建全过程

这里展示的是我们搭建第一个微服务——订单服务的过程。
第一步:创建父项目 spring-cloud-demo
这个项目的职责是统一管理所有子模块依赖和版本。
<!-- pom.xml -->
<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>spring-cloud-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>

<dependencyManagement>
<dependencies>
<!-- 统一管理 Spring Cloud 版本 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2020.0.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
第二步:创建订单服务模块 order-service
这是一个标准的 Spring Boot 工程,加入 Spring Cloud Starter NetFlix 相关依赖即可注册到 Eureka 中。
@SpringBootApplication
@EnableDiscoveryClient
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
对应的配置文件:
# application.yml
server:
port: 8081
spring:
application:
name: order-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
启动之后访问 Eureka 控制台:http://localhost:8761/,就能看到订单服务成功注册进来了。
第三步:服务间调用与负载均衡(Feign + Ribbon)
订单服务需要调用用户服务获取用户信息:
@FeignClient(name = "user-service")
public interface UserServiceClient {
@GetMapping("/users/{userId}")
User getUserById(@PathVariable Long userId);
}
Feign 默认集成了 Ribbon,会自动实现客户端负载均衡。
第四步:加个网关(Gateway)
网关我们选择的是 Spring Cloud Gateway。
主类直接使用:
@SpringBootApplication
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
配置文件:
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/user/**
filters:
- StripPrefix=1
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/order/**
filters:
- StripPrefix=1
这样外部请求就可以统一走 /api/xxx/xxx 进入对应服务。
实战中的踩坑经验分享
在实际开发过程中,我们遇到不少“小坑”,下面几个印象比较深的:
坑1:服务注册失败?看看防火墙!
初期部署时,服务总是注册不上。查了半天网络,最后发现是生产环境服务器禁用了默认的 8761 端口。解决方法就是在配置里明确指定:
eureka:
instance:
non-secure-port-enabled: true
secure-port-enabled: false
坑2:Feign 不支持 GET 请求传 POJO?
有一次我们在 Feign 接口中用了一个复杂的对象做参数,结果报错。原来是 Feign 默认不支持 GET 方法传复杂对象参数(会被转成 URL 查询字符串)。建议的做法是改用 @SpringQueryMap 注解或改为 POST。
坑3:网关路径转发规则配置错误导致 404
在配置 Gateway 的时候没注意路径前缀匹配规则,有时候 /api/user 匹配不到 /api/user/123,后来改成使用通配符:
predicates:
- Path=/api/user/**
坑4:多个服务实例共享数据库连接池
早期没用连接池时,服务一扩容就出现连接数打满数据库的情况。后来引入了 HikariCP,并根据并发量调整最大连接数:
spring:
datasource:
hikari:
maximum-pool-size: 20
上线后的效果与收益总结
迁移完成后,我们的系统发生了明显的变化:
✅ 部署速度提升5倍以上:每个服务独立构建发布,不需要停机全量更新;
✅ 可用性更高:订单服务宕掉不会影响用户登录等功能;
✅ 可伸缩性强:高峰期能动态扩容特定服务节点;
✅ 团队协作更顺畅:各组负责各自的服务模块,代码冲突减少很多。
虽然微服务也带来了一些新的挑战(如服务监控、日志聚合、链路追踪等),但我们陆续引入了 Zipkin、Prometheus + Grafana 来解决问题。
给读者的几点建议
如果你正在考虑是否要使用 Spring Cloud 或者刚刚入门,这里有几个建议可以参考:
- 不要为了微服务而微服务:评估清楚当前项目是否真的需要拆分,避免过度设计。
- 重视基础设施建设:日志、监控、配置中心、熔断机制,这些才是微服务真正的护城河。
- 做好服务边界划分:前期多思考业务领域模型,避免后期服务之间频繁调用。
- 善用社区资源:Spring Cloud 社区非常活跃,很多问题都能找到现成的解决方案。
- 持续学习新技术:Kubernetes、Docker、Istio 等相关技术也在不断演进,掌握它们会让你更有竞争力。
结语:技术永远服务于业务,而我们要做的就是让服务更可靠
从最初的单体应用到如今的微服务体系,这一路上我们踩过坑、绕过弯、写错过不少代码,但也收获了许多宝贵的经验。
微服务不是银弹,但它确实在某些场景下解决了我们面临的实际问题。希望这篇真实的分享能够帮到正在学习 Spring Cloud 和微服务的朋友,少走一些弯路,更快地踏上通往高可用系统的道路。
如果你们也有类似的转型经历或者踩过什么特别大的坑,欢迎留言交流~技术这条路,从来都不是一个人在战斗。💪
本文内容基于笔者亲身经历撰写,如有雷同纯属巧合,请尊重原创。

评论 0