Spring Cloud从零开始:一个后端开发者的微服务入门实战分享
开篇:为什么我决定写这篇文章?

作为一个在互联网公司工作多年的后端开发者,我经历过从单体架构到分布式、再到微服务架构的完整演变过程。特别是在公司业务快速增长的那几年,我们不得不面对越来越多的系统复杂性和技术挑战。
2019年的时候,我参与了一个全新的电商平台重构项目。原本我们是用Spring Boot做的单体应用,随着用户量上涨和新功能需求的激增,系统越来越吃力,部署也变得频繁且容易出错。最终团队决定拆分微服务,使用Spring Cloud来搭建整套微服务架构。
刚开始的时候,我也是一头雾水:服务注册与发现怎么配置?API网关要怎么设计?各个服务之间如何通信?还有熔断、限流、配置中心这些听起来高大上的概念……统统都需要一边学一边实践。
今天我想借这篇真实经历的技术分享文章,结合我在那个项目中的经验教训,和大家一起从零开始学习Spring Cloud微服务。如果你是一个刚接触微服务的新手或者正在犹豫要不要上手Spring Cloud,希望这篇文章能让你少走一些弯路。
问题描述:从单体应用到微服务,我们的痛

那个电商平台的原始版本是一个典型的单体架构:
- 所有业务逻辑都在同一个jar包里
- 数据库共用一张表(甚至没有分库分表)
- 每次发布必须整个项目重新打包、重启
- 新人接手困难,部署成本高
- 随着流量增长,经常出现接口超时甚至服务器崩溃
具体来说,我们遇到了几个典型的问题:
部署效率低下
每个修改哪怕只是前端文案,都要重跑一遍CI/CD流程。一次构建可能需要5分钟以上,测试环境还要反复等待。代码耦合度太高
订单模块和商品模块互相依赖严重,改一个地方经常牵一发动全身。性能瓶颈明显
商品搜索接口响应时间长,在高峰期经常出现慢查询甚至超时。扩展性差
想给某个服务做横向扩容?对不起,只能整个应用一起扩。
这些问题让我们意识到,是时候尝试微服务了。
解决方案:Spring Cloud + 微服务架构初探
我们的目标很明确:
- 将原有单体应用拆分成多个独立的服务
- 实现服务治理,包括注册发现、负载均衡、容错处理等
- 构建统一的API网关进行路由和鉴权
- 实现配置集中管理
- 提供链路追踪能力,方便排障
于是我们选择了Spring Cloud这一整套微服务解决方案,并围绕它搭建了基础架构平台。主要技术选型如下:
| 功能点 | 技术组件 |
|---|---|
| 服务注册与发现 | Eureka Server |
| 负载均衡 | Ribbon + RestTemplate / Feign |
| API网关 | Zuul(后期换成Gateway) |
| 配置中心 | Spring Cloud Config |
| 分布式事务 | Seata(简单场景下直接本地事务+补偿机制) |
| 日志与监控 | ELK + Zipkin |
| 熔断限流 | Hystrix(后来换成了Sentinel) |
接下来,我会重点讲我们是怎么一步步搭起这个框架的。
代码实践:Spring Cloud微服务起步实例
1. 创建Eureka Server —— 注册中心
这是我们第一个启动的服务。用于管理所有微服务的注册和发现。
# application.yml
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

// 启动类
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
访问 http://localhost:8761,你会看到Eureka控制台界面。
2. 创建商品服务(Product Service)
每个微服务都向Eureka注册自己。
# product-service的application.yml
spring:
application:
name: product-service
server:
port: 8081
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
@RestController
@RequestMapping("/products")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/{id}")
public ResponseEntity<Product> getProductById(@PathVariable Long id) {
return ResponseEntity.ok(productService.getProductById(id));
}
}
启动之后可以在Eureka页面看到这个服务。
3. 创建订单服务(Order Service),调用商品服务
这时候就需要用Ribbon或Feign来做服务间调用了。
使用Feign:
feign:
client:
config:
default:
http:
enabled: true
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
@FeignClient(name = "product-service")
public interface ProductServiceClient {
@GetMapping("/products/{id}")
Product getProductById(@PathVariable("id") Long id);
}
@Service
public class OrderService {
@Autowired
private ProductServiceClient productClient;
public Order createOrder(Long productId) {
Product product = productClient.getProductById(productId);
// 处理订单创建逻辑
}
}
这样就实现了服务间的调用。
踩坑经验:那些“小坑”让人印象深刻
虽然整体方案可行,但实际开发中我们也踩了不少坑。这里分享几个印象深刻的案例。
坑一:Feign Client调用失败,找不到服务
报错信息类似:
LoadBalancerException: No instances available for service
原因是:
- Eureka没同步上来
- 服务名拼错了
- 没有启动Eureka Server
- Feign未启用Hystrix(默认不启用)
解决办法:
- 检查Eureka控制台看服务是否在线
- 检查Feign注解里的name值是否一致
- 在启动类加
@EnableFeignClients - 如果开了Hystrix注意降级逻辑
坑二:服务注册慢、延迟明显
有时候服务启起来以后,在Eureka上需要过好几秒才能显示出来,导致其他服务调不到。
我们通过调整Eureka的刷新频率和缓存时间解决:
eureka:
client:
registry-fetch-interval-seconds: 5
instance:
lease-expiration-duration-in-seconds: 10
lease-renewal-interval-in-seconds: 5
不过要注意这种修改会增加网络开销和内存占用。
坑三:Zuul网关跨域问题
前端调用网关地址的时候遇到CORS报错。最初我们以为是网关的问题,结果排查下来发现Zuul本身不处理跨域,是被代理的下游服务没有设置。
解决方式是在下游服务里加上全局跨域过滤器:
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.exposedHeaders("Authorization");
}
}
如果是使用Gateway的话也可以在网关层面统一处理。
效果总结:从混乱到有序

经过两个月的努力,我们的微服务架构逐渐稳定上线。整个项目的收益体现在以下几个方面:
- 部署效率提升:可以按模块单独发版,不再需要每次全部重启,构建时间减少70%+
- 系统稳定性提高:核心服务如支付、库存等进行了隔离,避免故障扩散
- 可扩展性强:高峰期能快速对热点服务做水平扩容
- 开发协作更清晰:每个服务边界明确,多人协作更顺畅
更重要的是,我们建立了一套标准化的服务模板,后续新项目基本都可以复用这个架构结构,极大提升了开发效率。
经验分享:几点忠告送给刚起步的同学
如果你现在也是第一次接触微服务,准备用Spring Cloud作为技术栈,以下是我根据这几年经验整理的一些建议:
✅ 1. 不要为了拆分而拆分
很多人一开始就把所有服务全都拆得特别细,结果后面发现根本无法维护。建议前期拆分保持适度粒度即可,比如先按照业务领域划分(商品、订单、支付),后续再细化。
✅ 2. 优先考虑服务治理
微服务一旦多了,服务治理就是首要任务。注册发现、熔断限流、配置中心这些基础设施要尽早规划,不要等到系统出问题再去补。
✅ 3. 日志和监控必须同步建设
你一定会在生产环境中遇到各种奇怪的问题,所以一开始就要接入日志收集(ELK)、链路追踪(Sleuth + Zipkin)以及健康检查(Actuator + Prometheus)。
✅ 4. 接口设计要有规范
服务之间的调用要有一致的格式,比如请求参数、返回封装、错误码定义等。否则后期维护起来非常痛苦。
✅ 5. 数据库设计同样重要
微服务不是数据拆分的理由。你可以先共享数据库,后期根据业务发展慢慢做分库分表、引入中间件。别一开始就搞得太复杂。
写在最后:技术没有银弹,但方向要对
说实话,微服务并不是万能药,也不是每个项目都适合拆成微服务。它带来的不仅是架构上的灵活性,也有运维、协同、测试等方面的复杂性。选择这条路之前,你要问自己几个问题:
- 我们的业务真的需要吗?
- 团队是否有足够的支撑能力?
- 是否已经具备相应的自动化工具链?
对我而言,那次转型确实是个挑战,但也带来了不小的成长。Spring Cloud作为一套成熟的开源微服务框架,虽然有些组件已进入维护状态(比如Zuul、Hystrix),但它仍然提供了完整的微服务治理思路,是很多公司的首选。
如今Spring生态又有了Spring Cloud Alibaba这样的增强扩展,结合Nacos、Sentinel、Dubbo等,更加贴近国内企业的需求。
无论你是刚入行的小白,还是有多年经验的工程师,我都鼓励你在合适的时机多去尝试新技术、新架构。只有通过实际项目中的落地,你才能真正理解它的优缺点,进而做出更明智的技术决策。
愿你也能在微服务的世界里走得更远、更稳。共勉!

评论 0