Spring Cloud从零开始:微服务入门指南(项目实战篇)
引言:为什么我决定写这篇文章

去年年初,我所在的公司决定将原有的单体应用重构为微服务架构。作为后端技术负责人,我在整个过程中踩了不少坑、也积累了大量经验。现在回想起来,当时团队面对Spring Cloud这套庞大的生态体系时是既兴奋又忐忑的。
这篇文章不是一篇干巴巴的技术手册,而是一个真实项目的复盘笔记。我会以一个完整项目的开发为主线,结合我们在实际工作中遇到的问题和解决方案,带大家一步步走进Spring Cloud的世界——从最基础的注册中心、配置中心讲起,一直到网关、服务调用、数据库设计和生产部署。
希望这篇“带着体温”的分享,能帮你少走一些弯路,更快上手微服务。
项目背景与挑战

我们原本维护的是一个电商平台的后台系统,采用Java + Spring Boot开发,前后端分离。随着业务增长,代码臃肿、部署困难、性能瓶颈等问题逐渐显现出来。于是我们决定尝试微服务化改造,目标是要实现以下几点:
- 各模块独立部署,互不影响
- 提升整体系统的稳定性和可扩展性
- 更好地支持后期多团队并行开发
- 实现统一的服务治理和可观测性
但挑战也不小:
- 技术选型复杂,Spring Cloud全家桶有几十个组件,怎么组合才合理?
- 多服务之间如何高效通信?
- 数据库要不要分库?服务粒度怎么划分?
- 配置如何集中管理?
- 如何快速定位线上问题?
这些问题在最初的调研阶段就让我们头疼不已。
解决思路与技术方案

1. 服务拆分规划
我们先对原系统进行了模块梳理,大致拆分为以下几个核心微服务:
- 用户服务(user-service):用户账户、权限、登录等
- 商品服务(product-service):商品信息管理
- 订单服务(order-service):处理订单流程
- 库存服务(inventory-service):库存相关逻辑
- 支付服务(payment-service):支付通道接入
服务之间的关系如下图所示(简化版):
+------------------+
| Gateway API |
+--------+---------+
|
+-----------+------------+
| | |
+----------+--+ +----+-----+ +---+----+
| user-service | | product-serivce | ...
+--------------+ +-----------------+
2. 使用Spring Cloud生态搭建服务体系
我们最终选用的核心组件包括:
- Nacos:服务注册发现 & 配置中心
- Gateway:统一路由网关
- Feign / OpenFeign:服务间远程调用
- Sentinel:限流熔断
- Seata:分布式事务(后来加入)
- SkyWalking:链路追踪
- MySQL分表 + MyBatis Plus:数据库访问层
接下来,我就按顺序讲讲几个关键点是怎么做出来的。
核心实践:动手搭起来
1. 注册中心+Nacos配置中心
我们先选择Nacos作为注册中心和配置中心。比起Eureka+EConfig的组合,Nacos更适合国产化场景,而且控制台更友好。
# application.yml 用户服务示例
server:
port: 8080
spring:
application:
name: user-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
config:
server-addr: localhost:8848
file-extension: yaml
management:
endpoints:
web:
exposure:
include: "*"
启动之后就能自动注册到Nacos里了。
🎯 小贴士:建议本地跑一个Nacos单机版本开发测试,正式环境要使用集群。
2. 接口路由与安全管控:引入Gateway
我们用Spring Cloud Gateway来统一API入口,并集成鉴权逻辑。比如下面这段配置,实现了不同服务的转发规则:
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/user/**
filters:
- StripPrefix=2
- id: product-service
uri: lb://product-service
predicates:
- Path=/api/product/**
filters:
- StripPrefix=2
在这个基础上我们还做了JWT token验证,放在Filter里统一处理。
3. 服务调用:OpenFeign还是Dubbo?
我们选择了OpenFeign作为服务间调用方式,主要是为了保持REST风格一致性和减少学习成本。
// 在订单服务中调用用户服务获取用户信息
@FeignClient(name = "user-service")
public interface UserServiceClient {
@GetMapping("/users/{id}")
UserDTO getUserById(@PathVariable("id") Long userId);
}
当然你也可以结合Ribbon做负载均衡,默认就是OK的。
4. 分布式事务 Seata 初体验
当订单扣减库存的时候,我们遇到了数据一致性问题。最初是用了本地事务加try-catch重试,效果并不好。
后来引入了Seata,通过全局事务协调器(TC)、资源管理器(RM)等机制,可以较好地控制跨服务的一致性。
<!-- 添加seata依赖 -->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.6.1</version>
</dependency>
然后在方法加上注解即可开启分布式事务:
@GlobalTransactional
public void createOrder(Long productId) {
// 调用库存服务扣库存
inventoryService.reduceStock(productId);
// 保存订单记录
orderRepository.save(...);
}
不过,Seata也不是银弹,我们初期因为锁竞争频繁导致TPS下降明显。后来优化了隔离级别,并且把部分非强一致性操作放到了异步队列中处理。
5. 数据库设计与接口规范
微服务的一个难点在于:数据模型该如何划分?我们在初期犯了一个错误:每个服务都建了一套自己的用户表、产品表,结果导致数据不一致。
后面改成了“领域驱动设计”,明确谁拥有核心数据源,比如:
- 用户服务持有完整的User表
- 其他服务只能引用userId字段,不能复制全量数据
另外,所有对外接口我们坚持三个原则:
- 统一使用JSON格式返回封装对象
- 定义标准化的错误码和提示信息
- 所有接口都做接口文档Swagger自动生成
生产上线那些事:运维与监控
微服务上生产以后才发现真正的挑战才刚刚开始。
日志聚合 vs 链路追踪
我们采用了SkyWalking来做APM监控,它可以清晰展示每个请求在各个服务中的耗时,甚至能看到SQL执行时间。
日志方面,我们使用ELK做聚合,同时每条日志都带上TraceID,方便排查异常链路。
健康检查 & 自动重启
我们在各服务中集成了Actuator健康检查,并在Prometheus中配置了告警规则。比如某个服务CPU或内存超过阈值自动告警。
Kubernetes也是我们上线的重要工具,帮助我们实现了服务编排、滚动更新、蓝绿发布等功能。
网络安全方面的小细节
- 所有对外暴露的API都做了HTTPS加密
- 内部服务之间启用Token签名认证
- 网关层做IP白名单限制访问来源
- 敏感接口设置RateLimit防止刷单攻击
那些年我们一起踩过的坑
1. Feign调用失败却收不到异常?
刚开始的时候,我们发现某些Feign调用会直接超时,抛出的异常也没有明确信息。排查下来发现:
- 没有开启Feign客户端的日志打印
- 负载均衡策略不合理导致节点不可达
- 缺少熔断机制(后来引入Sentinel做降级)
解决办法很简单:增加Sentinel熔断、日志开关打开、配置合理的fallback策略。
2. Nacos元数据丢失?
有时候我们会发现在某次重启Nacos之后,部分服务没有正确注册上来。查资料才知道原来默认元数据是存储在内存里的,需要手动开启持久化配置(比如用MySQL)。
3. 频繁Full GC导致服务抖动?
线上有一次多个服务突然响应变慢,日志显示出现频繁GC。后来通过JVM参数调整(Xms=Xmx、CMS升级G1、合理设置MaxMetaspaceSize)解决了这个问题。
成果与收获
经过三个月的努力,我们的平台完成了微服务初步迁移:
- 部署效率提升近三倍,支持灰度发布
- 单个服务宕机不会影响全局系统
- 新人更容易理解系统结构,快速定位问题
- 监控体系建设完善,具备实时报警能力
- 支持未来横向扩展更多业务模块
更重要的是,团队成员对云原生架构有了更深的理解,后续也开始逐步向K8s转型。
给开发者的几点建议
如果你刚开始接触Spring Cloud,或者打算着手微服务项目,这些建议可能对你有用:
- 不要追求大而全,先从小规模服务拆分入手,逐步迭代
- 优先考虑服务治理能力:注册、发现、调用、限流、链路追踪这些才是核心
- 数据库不要过早分表分库,除非确实面临性能瓶颈
- 接口规范一定要统一,否则后期联调痛苦不堪
- 运维体系要提前规划,监控、日志、自动化构建都不能少
- 不断尝试新技术,但要平衡稳定性与创新性之间的关系
最后想说一句:微服务不是灵丹妙药,它是一种复杂性转移的艺术。只有真正理解背后的设计理念,才能用好这把双刃剑。
结语:写在最后
这篇分享源于我个人亲身参与的真实项目,文章中提到的所有问题我都经历过、纠结过、也踩过不少坑。
我希望通过这样的方式,能把知识和技术转化成经验传递下去。也希望每一个正在探索微服务之路的开发者,都能从中找到属于自己的那份答案。
如果你也在进行微服务改造,欢迎留言交流,一起探讨更好的实践方式 👇

评论 0