Spring Cloud从零开始:微服务入门指南
去年我们公司决定启动一个新项目,目标是重构一个原本单体的电商平台。这个平台在过去几年中功能越加越重,部署困难、维护成本高,团队协作效率也很低。为了应对这些痛点,我们决定转向微服务架构,并选用Spring Cloud作为技术栈。
我负责的是其中一个核心子系统的开发——订单中心。在参与整个微服务体系建设的过程中,我也踩了不少坑,但也积累了很多实战经验。今天就来分享一下,作为一个后端工程师如何从零开始搭建一个基于Spring Cloud的微服务系统,以及我在实际工作中的体会。
项目背景与技术选型

先介绍一下当时的项目背景。原始系统是一个单体Java应用,所有的业务逻辑和数据库操作都在一个WAR包里完成,代码结构混乱,耦合严重,每次上线都像“拆弹”一样小心翼翼。
我们希望做的新系统要满足几个基本要求:
- 模块解耦,便于扩展
- 独立部署,提高交付效率
- 分布式能力支持高并发
- 有统一的服务注册发现机制
- 支持服务间通信、熔断降级等治理能力
最终我们的技术选型如下:
- Spring Boot:用于快速构建独立运行的服务实例
- Spring Cloud Alibaba(Nacos):代替Eureka做服务注册发现,Nacos还提供配置中心能力
- OpenFeign + LoadBalancer:实现声明式服务调用
- Sentinel:做熔断限流
- MySQL分库分表+MyBatis Plus
- Spring Cloud Gateway:统一API网关
- RabbitMQ:用于异步消息通知
- Seata:分布式事务方案(未最终采用,后面会解释)
遇到的第一个挑战:服务注册与发现怎么选?

最开始我们是按照经典的Spring Cloud方式准备使用Eureka和Zookeeper,但后来发现Nacos其实是更好的选择,特别是在国内环境,社区活跃度高、集成简单,还能做配置中心,非常适合我们这种中小型项目。
不过也踩了一个坑:一开始没搞清楚Nacos集群模式下的持久化问题,导致一次测试环境宕机之后服务注册信息全丢了。后来改成了MySQL持久化存储才解决了这个问题。
解决方法很简单:配置Nacos的数据源为MySQL,启用持久化模式:
spring:
datasource:
platform: mysql
mysql:
ip: 127.0.0.1
port: 3306
database: nacos_config
username: root
password: 123456
这个小插曲也提醒我,不要一味追求“轻量”,生产级别的服务注册中心必须考虑数据可靠性。
微服务划分实践:订单中心怎么切出去?
我们把原来的单体系统拆成了五个主要微服务:
- 用户服务(User Service)
- 商品服务(Product Service)
- 订单服务(Order Service)
- 支付服务(Payment Service)
- 消息通知服务(Message Service)
订单服务是其中最复杂的,涉及用户下单、库存扣减、支付跳转等多个流程。这个时候我深刻体会到一点:
微服务的划分不是按功能,而是按照领域边界和一致性需求来设计。
举个例子:订单创建的时候需要访问库存服务。这个时候你可能会想直接远程调用,但我建议优先通过异步消息来处理。比如使用RabbitMQ发送一个“订单已生成”的事件,由库存服务监听并执行库存扣除。
这样可以降低服务间的直接耦合,也能避免分布式事务的复杂性。
关键实践:Feign、Gateway 和 Sentinel 怎么一起玩?
Feign 调用失败的问题
我们在服务间通信时最早使用了Feign,默认情况下是基于JDK的URLConnection进行HTTP请求,性能一般,而且一旦服务挂掉或者网络异常,很容易出现雪崩效应。
这时候我们引入了LoadBalancer(负载均衡器),并结合Sentinel做熔断降级。
一段典型的Feign客户端调用如下:
@FeignClient(name = "product-service")
public interface ProductServiceClient {
@GetMapping("/products/{id}")
Product getProductById(@PathVariable("id") Long id);
}
然后,在主类上开启FeignClients和Sentinel的支持:
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
同时,在application.yml中启用Sentinel熔断策略:
feign:
sentinel:
enabled: true
熔断降级的效果
有了Sentinel之后,一旦某个服务不稳定,Feign就会触发熔断规则,返回预设的fallback逻辑,比如返回一个缓存数据或者提示:“系统繁忙,请稍后再试”。
这大大提升了系统的整体健壮性。
数据库设计的心得:别盲目分库分表!
很多人一上来就想着要分库分表,但其实对于刚起步的微服务系统来说,这样做反而带来额外的复杂性。
我们在订单服务初期并没有立即分库,而是在MySQL层面做了一些优化:
- 使用InnoDB引擎,设置合适的索引
- 对高频查询字段如
order_no建立唯一索引 - 定期分析慢SQL,使用Explain查看执行计划
- 引入Redis作为热点订单缓存
真正等到订单量突破百万级之后,才开始分库分表的设计,采用Sharding-JDBC进行垂直拆分和水平拆分。
我的建议是:
初期微服务应以快速迭代为主,数据库结构清晰、索引合理即可;后期再根据性能瓶颈逐步优化。
生产运维经验分享:日志、监控和灰度发布
微服务一旦上线,最重要的就是可观测性。我们做了以下几件事:
日志收集
使用Logback写入本地文件,配合Filebeat同步到Elasticsearch,然后Kibana可视化。这种方式简单有效,适合中小团队。
监控告警
Prometheus + Grafana实时监控各服务的QPS、响应时间、线程池状态等关键指标,结合AlertManager做钉钉/邮件报警。
灰度发布
在Spring Cloud Gateway中配置路由权重,将少量流量导向新版本,观察运行稳定后再全部切换。
例如:
spring:
cloud:
gateway:
routes:
- id: order-new
uri: lb://order-service-v2
predicates:
- Path=/api/order/**
filters:
- StripPrefix=1
- Weight=orderGroup, 30 # 新版本30%
- id: order-old
uri: lb://order-service
predicates:
- Path=/api/order/**
filters:
- StripPrefix=1
- Weight=orderGroup, 70 # 旧版本70%
那些年我们一起踩过的坑
没有统一的日志追踪ID
最早各服务日志无关联,查问题非常困难。后来我们引入MDC日志上下文跟踪,每个请求进来生成一个TraceId,贯穿所有服务。Feign默认超时太短
默认情况下Feign的连接和读取超时只有1秒,根本不够用。后来调整到3秒左右,并且加上重试机制:feign: client: config: default-config: connectTimeout: 3000 readTimeout: 3000Nacos配置更新不生效
有时候修改了Nacos上的配置,服务那边并没有刷新。检查后发现遗漏了Spring Cloud的自动刷新注解@RefreshScope,记得给每个Bean加上。
结果与收益
经过三个月的努力,整个微服务架构初步成型。虽然还有一些改进空间,但我们已经取得了明显的收益:
- 各个模块职责清晰,开发效率显著提升
- 故障范围被隔离在单一服务内,不会影响全局系统
- 可以灵活地进行灰度发布、弹性扩缩容
- 服务间通信稳定可控,依赖管理更加规范
特别是当遇到双十一压测压力时,系统的表现非常稳定,接口成功率保持在99.8%以上。
我的经验总结与建议
如果你现在正准备踏上微服务的道路,不妨记住这几个建议:
不要盲目复制大厂架构
小团队或新项目更适合从简单做起,先把服务拆通、接口理清,再逐步加上高级功能。重视服务治理
服务注册、健康检查、熔断降级、链路追踪这些基础设施必须提前规划好。别急着引入分布式事务
Seata这类解决方案确实强大,但对业务侵入性大,运维成本高。能通过异步解耦解决的问题,尽量不用强一致性。微服务不是银弹
它带来的好处是以更高的运维复杂度为代价的。权衡利弊,选择适合自己业务阶段的架构。多写文档、多沟通
微服务意味着多个团队协同作战,接口定义、调用顺序、错误码标准这些必须统一并文档化,否则合作起来会很痛苦。
结语
一路走来,Spring Cloud帮我们打开了通往高可用架构的大门,也让我更深刻地理解了什么是真正的工程思维:不是堆砌最先进的技术,而是找到最适合当前场景的解决方案。
希望这篇文章能给正在摸索微服务的同学一些启发。如果你们也在用Spring Cloud,欢迎留言交流经验,一起进步!
如有需要,我可以继续深入讲解具体的模块实现、数据库迁移策略、服务注册细节等内容。

评论 0