Spring Cloud从零开始:微服务入门指南
上周五晚上十点,我戴着耳机听着 Lo-fi Hip Hop 写代码(别笑,这玩意儿真能治焦虑),突然收到产品发来的新需求:“咱们要搞个去中心化的供应链溯源系统,用区块链存关键交易记录。”我当时差点一口老血喷在机械键盘上——我们后端还在单体架构里挣扎,连数据库读写分离都没做好,现在就要上链?
但转念一想,反正干了三年多,也该换个环境了。跳槽简历上总不能只写“精通 CRUD”吧?于是咬咬牙,决定把整个系统重构为微服务架构,顺便把 Spring Cloud 这套东西彻底吃透。
说真的,如果不是被逼到墙角,谁愿意在 deadline 前两周重写整个系统架构啊!
为什么是 Spring Cloud?不是 Go?不是 Service Mesh?
先澄清一个误区:很多人觉得“微服务 = 必须用 Go”,或者“新项目不上 Kubernetes 就是土鳖”。但现实是——我们团队全是 Java 老兵,运维对 Spring Boot 熟得跟自家厨房一样,而产品经理下周就要 demo。时间不等人。
Go 确实快、轻量、部署简单,我也在业余时间用它写过几个小工具(比如自动抓取 GitHub Star 的脚本)。但在企业级复杂业务场景下,Spring 生态的成熟度、监控能力、事务管理、以及那堆开箱即用的 starter,真的香。尤其是 Spring Cloud Alibaba 这一套,Nacos + Sentinel + Seata,国内云厂商支持得好,文档也全。
至于区块链?别被营销话术带偏了。我们只是用 Hyperledger Fabric 存哈希值做防篡改校验,核心业务逻辑还是跑在微服务里。区块链不是银弹,更不是架构选型的理由。
从单体到微服务:我的踩坑日记
我们的老系统是个典型的“上帝类”应用:一个 Spring Boot 项目,Controller 里嵌着 DAO,Service 层调用第三方 API 还没加熔断,数据库连接池配置还是默认的 10。去年双11,流量一上来,直接 OOM,运维半夜打电话骂街。
所以这次重构,我给自己定了三个原则:
- 高内聚低耦合:每个服务只干一件事
- 可观测性优先:日志、指标、链路追踪必须到位
- 可维护性 > 性能:代码要让实习生也能看懂(别笑,我们真招了个实习生)
第一步:服务拆分
我把系统拆成了四个核心服务:
user-service:用户认证、权限order-service:订单创建、状态流转product-service:商品信息、库存blockchain-gateway:对接 Fabric,提交交易哈希
注意:
blockchain-gateway是独立服务!千万别把区块链 SDK 直接塞进业务代码,否则调试起来能让你怀疑人生。
第二步:注册中心选型
纠结过 Eureka vs Consul vs Nacos。最后选了 Nacos,原因很现实:
- 支持 AP + CP 切换(开发用 AP,生产切 CP)
- 中文文档友好
- 阿里系,和我们用的阿里云无缝集成
# bootstrap.yml (每个服务都要配)
spring:
application:
name: order-service
cloud:
nacos:
discovery:
server-addr: ${NACOS_HOST:localhost}:${NACOS_PORT:8848}
启动后,打开 http://localhost:8848/nacos,看到服务列表亮起绿色小点,那一刻真的爽——比看到工资条还开心。
关键配置:让微服务“活”起来
光注册还不够,微服务之间怎么通信?怎么防雪崩?怎么传用户上下文?
Feign + Ribbon:声明式调用
以前写 RestTemplate,URL 拼得像意大利面。现在用 Feign,接口定义即文档:
@FeignClient(name = "product-service", fallback = ProductClientFallback.class)
public interface ProductClient {
@GetMapping("/products/{id}")
Product getProduct(@PathVariable("id") Long id);
}
配合 @EnableFeignClients,注入就能用。而且天然集成 Ribbon 负载均衡,不用自己写轮询逻辑。
吐槽一句:测试同事总抱怨“你们接口又 500 了”,其实 90% 是下游服务挂了。所以 fallback 必须写!
Sentinel:熔断限流保命符
线上最怕级联失败。上次就是因为 product-service 响应慢,拖垮了整个 order-service。这次上了 Sentinel,配置如下:
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080
datasource:
ds1:
nacos:
server-addr: localhost:8848
data-id: order-service-sentinel
group-id: DEFAULT_GROUP
rule-type: flow
在 Sentinel Dashboard 里设置 QPS 阈值,超了就快速失败,而不是傻等。还能根据 RT、异常比例自动熔断。上线后,再也不用半夜接 PagerDuty 报警了。
分布式事务:Seata 来救场
订单创建涉及扣库存、生成流水、发消息……传统 JTA 太重。我们用了 Seata AT 模式,只需要:
- 在每个服务的数据源包装成
DataSourceProxy - 全局事务注解
@GlobalTransactional
@GlobalTransactional
public void createOrder(OrderRequest request) {
// 1. 扣库存 (product-service)
// 2. 创建订单 (本地)
// 3. 发送MQ (异步)
}
虽然性能有损耗(毕竟两阶段提交),但保证了数据一致性。对于金融相关操作,这点代价值得。
数据库设计:别让微服务变成“分布式单体”
很多团队拆了服务,但数据库还是共用一个 schema,这叫“伪微服务”。
我的做法:
- 每个服务独享数据库(甚至不同实例)
- 禁止跨服务直接查表!只能通过 API
- 用 事件驱动 解耦:订单创建成功 → 发 Kafka 事件 → 库存服务消费并更新
-- order-service 的 orders 表
CREATE TABLE orders (
id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL,
status VARCHAR(20) NOT NULL, -- PENDING, PAID, CANCELLED
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- product-service 的 inventory 表(完全独立)
CREATE TABLE inventory (
product_id BIGINT PRIMARY KEY,
stock INT NOT NULL
);
初期会多几次网络调用,但换来的是真正的解耦。后期想把 product-service 用 Go 重写?没问题,只要 API 兼容就行。
生产环境那些事儿
开发爽了,上线才是地狱模式。分享几个血泪经验:
| 问题 | 解决方案 |
|---|---|
| 日志分散,查问题像大海捞针 | 统一接入 ELK,用 traceId 串联全链路 |
| 服务启动顺序依赖 | 用 Nacos 的 @ConditionalOnProperty 控制初始化顺序 |
| 配置文件泄露敏感信息 | 敏感配置走 Nacos 加密插件 + KMS |
| 网络抖动导致调用失败 | Feign 配置 Retryer,重试 2 次 |
特别提一下 链路追踪。集成 SkyWalking 后,在 UI 上能看到请求从 gateway 到 order-service 再到 product-service 的完整路径,耗时一目了然。有一次发现 80% 时间花在数据库连接获取上,原来是连接池太小——这种问题靠肉眼根本看不出来。
和 Go 微服务对比?其实没必要对立
我知道有些 Go 粉要跳脚了:“Java 太重!Go 才是未来!” 但技术选型不是宗教信仰。
我们内部其实有个用 Go 写的轻量级网关,处理 TLS 卸载和 IP 黑名单,性能确实比 Spring Cloud Gateway 高 30%。但核心业务?还是 Java 更稳。混合架构才是常态。
如果你团队熟悉 Go,且业务简单(比如纯 API 转发),那 Go 微服务很合适。但涉及复杂事务、遗留系统集成、大量中间件,Spring Cloud 的生态优势就出来了。
最后:微服务不是终点,而是起点
折腾了一个月,系统终于跑起来了。压力测试下,QPS 从原来的 300 提升到 2000+,最关键的是——任何一个服务挂掉,其他功能还能用。
上周给产品演示时,他问:“区块链在哪?” 我指了指后台日志里一闪而过的交易哈希,他点点头:“哦,那就行。” ——你看,技术人总在为那些看不见的地方拼命。
现在我的简历上可以写:“主导微服务架构升级,支撑日均百万级交易,集成区块链防篡改。” 跳槽底气足了点。
但说实话,最让我开心的不是这些,而是某天实习生跑来问我:“哥,这个 Feign 超时怎么配?” ——说明代码真的可读、可维护。这才是工程师的浪漫。
技术分享的意义,不就是让更多人少踩坑吗?
如果你也在被单体架构折磨,不妨试试 Spring Cloud。
记住:架构没有银弹,但有适合你团队的那颗子弹。
P.S. Cursor 又帮我自动生成了 200 行配置代码,我真的离不开它了……(狗头)

评论 0