Appearance
第65课:Spring Cloud 进阶
🎯 学习目标
- 理解微服务进阶治理问题:动态配置、限流熔断、链路追踪、分布式事务和网关治理。
- 掌握 Nacos Config 动态刷新、Sentinel/Resilience4j 限流降级、Gateway 过滤器的基本用法。
- 理解 Seata 等分布式事务方案的适用边界和代价。
- 能设计微服务故障保护策略,避免级联雪崩。
- 能识别“技术补丁掩盖架构问题”的场景。
📖 一、微服务进阶问题
基础微服务能跑起来后,会遇到更复杂的问题:
text
配置变更如何动态生效?
下游服务慢了如何保护自己?
接口流量突增如何限流?
一条请求跨多个服务如何追踪?
多个服务写数据库如何保证一致性?
网关如何做认证、灰度、限流?这些问题不是可选项。只要系统进入生产,就必须考虑。
📖 二、Nacos 配置动态刷新
依赖:
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>配置:
yaml
spring:
application:
name: order-service
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yaml动态刷新:
java
@RefreshScope
@RestController
public class ConfigController {
@Value("${order.timeout:3000}")
private int timeout;
@GetMapping("/config/timeout")
public int timeout() {
return timeout;
}
}注意:不是所有配置都适合动态刷新。数据库连接池、线程池等配置动态变更要谨慎。
📖 三、限流与熔断
限流:限制进入系统的请求量。
熔断:下游持续失败时,短时间内不再调用,直接快速失败或降级。
降级:返回兜底结果。
Sentinel 示例:
java
@Service
public class OrderService {
@SentinelResource(
value = "createOrder",
blockHandler = "createOrderBlocked",
fallback = "createOrderFallback"
)
public OrderResponse createOrder(OrderCreateRequest request) {
return doCreate(request);
}
public OrderResponse createOrderBlocked(OrderCreateRequest request, BlockException ex) {
throw new BusinessException("TOO_MANY_REQUESTS", "请求过多,请稍后再试");
}
public OrderResponse createOrderFallback(OrderCreateRequest request, Throwable ex) {
throw new BusinessException("ORDER_CREATE_FAILED", "下单失败,请稍后重试");
}
}blockHandler 处理限流,fallback 处理业务异常或下游异常。
📖 四、服务雪崩
雪崩链路:
text
库存服务变慢
订单服务线程被阻塞
订单服务连接池耗尽
网关请求堆积
用户服务也被拖慢
整个系统不可用保护手段:
text
超时
限流
熔断
降级
隔离
排队
快速失败远程调用必须设置超时:
yaml
spring:
cloud:
openfeign:
client:
config:
default:
connectTimeout: 1000
readTimeout: 3000📖 五、链路追踪
一条请求跨多个服务:
text
gateway -> user-service -> order-service -> payment-service没有 traceId 很难定位问题。
现代 Spring Boot 通常使用 Micrometer Tracing:
xml
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>日志中带 traceId:
text
2026-06-30 20:10:11 INFO [traceId=abc123, spanId=def456] create order链路追踪不是替代日志,而是把多个服务的日志和调用关系串起来。
📖 六、分布式事务
跨服务写多个数据库时,本地事务不够。
常见方案:
| 方案 | 特点 |
|---|---|
| 2PC/Seata AT | 接近强一致,依赖框架和代理 |
| TCC | Try/Confirm/Cancel,业务侵入强 |
| Saga | 长事务拆成多个步骤和补偿 |
| 可靠消息最终一致 | 用消息驱动状态推进 |
Seata 示例:
java
@GlobalTransactional(name = "create-order", rollbackFor = Exception.class)
public void createOrder(OrderCreateRequest request) {
orderService.create(request);
storageClient.deduct(request.getProductId(), request.getQuantity());
accountClient.deduct(request.getUserId(), request.getAmount());
}不要把分布式事务当成默认方案。很多业务用最终一致更稳、更可扩展。
📖 七、Gateway 过滤器
自定义过滤器:
java
@Component
public class TraceGatewayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String traceId = UUID.randomUUID().toString().replace("-", "");
ServerHttpRequest request = exchange.getRequest().mutate()
.header("X-Trace-Id", traceId)
.build();
return chain.filter(exchange.mutate().request(request).build());
}
@Override
public int getOrder() {
return -100;
}
}Gateway 适合做统一入口治理,但不能替代业务服务的权限和校验。
⚠️ 八、常见陷阱
1. 动态配置滥用
不是所有配置都能安全热更新。线程池、连接池、数据源等必须评估生命周期。
2. 降级返回假成功
降级不能欺骗调用方。失败就是失败,除非业务明确接受兜底数据。
3. 过度依赖分布式事务
分布式事务会降低性能并增加复杂度。优先从业务流程上避免强一致跨服务写。
4. 只在网关做权限
绕过网关、内部调用、配置错误都可能导致安全缺口。核心服务仍要做权限校验。
🆚 九、Java vs C 对比
| 维度 | C 微服务治理 | Spring Cloud 进阶 |
|---|---|---|
| 限流熔断 | 手写或接入库 | Sentinel/Resilience4j |
| 链路追踪 | 手动传播 traceId | Micrometer Tracing |
| 分布式事务 | 自研协议或消息补偿 | Seata/TCC/Saga |
| 网关扩展 | Nginx/OpenResty/自研 | Spring Cloud Gateway |
框架降低接入成本,但故障语义和业务一致性仍需要架构设计。
💡 十、最佳实践
- 所有远程调用必须有超时。
- 限流、熔断、降级要按接口重要性设计。
- 降级结果不能误导业务。
- 链路追踪和日志 traceId 必须统一。
- 分布式事务优先考虑最终一致和补偿。
- 网关做入口治理,服务内部仍要保护自己。
- 动态配置变更要有权限、审计和回滚。
- 微服务治理能力要通过压测和故障演练验证。
🔍 十一、自测问题
text
限流、熔断、降级分别解决什么问题?
blockHandler 和 fallback 有什么区别?
为什么远程调用必须设置超时?
链路追踪和普通日志是什么关系?
分布式事务有哪些常见方案?
为什么最终一致常常比强一致更适合微服务?
网关过滤器适合做什么?
为什么不能只依赖网关做安全?🧭 十二、稳定性治理清单
上线微服务前,至少确认:
text
每个 Feign 客户端是否设置超时?
核心接口是否有限流规则?
下游失败是否有降级策略?
降级是否会误导用户?
是否有 traceId 贯穿网关和服务?
是否监控错误率、P99 和熔断次数?
配置变更是否有审计?
分布式事务是否有补偿方案?稳定性治理必须在压测和故障演练中验证,不能只看配置文件。
🧪 十三、实战案例:库存服务慢
假设下单依赖库存服务:
text
库存服务响应从 50ms 变成 5s。
订单服务线程开始等待。
订单服务连接池占满。
网关请求堆积。
用户看到全站变慢。治理方案:
text
Feign 读超时设置为 1s。
库存扣减接口设置限流。
连续失败触发熔断。
下单接口返回明确失败,不假装成功。
记录 traceId 和失败原因。
告警通知库存服务负责人。这就是限流、熔断、降级和链路追踪组合使用的典型场景。
📌 十四、学习建议
建议做一次故障演练:
text
启动 user-service 和 order-service。
让 order-service sleep 5 秒。
观察 user-service 线程和响应时间。
加超时。
再加限流或熔断。
比较治理前后的表现。只有亲手制造过故障,才能理解微服务治理不是装饰。
📚 十五、治理能力选择表
| 问题 | 能力 |
|---|---|
| 请求太多 | 限流 |
| 下游持续失败 | 熔断 |
| 下游偶发慢 | 超时 |
| 非核心能力失败 | 降级 |
| 跨服务定位慢请求 | 链路追踪 |
| 配置要统一管理 | 配置中心 |
| 多服务写一致性 | 消息最终一致或分布式事务 |
| 入口统一控制 | 网关 |
治理能力要按问题选择,不要为了技术栈完整而全部堆上。
📌 十六、故障演练建议
至少演练:
text
下游服务宕机。
下游服务变慢。
配置中心不可用。
注册中心不可用。
网关限流触发。
消息堆积。
数据库慢查询。微服务系统的可靠性来自演练,不来自配置文件。
📌 十七、治理优先级
如果资源有限,优先级建议:
text
超时
指标和日志
限流
熔断
降级
链路追踪
故障演练
分布式事务治理没有超时和指标时,后面的治理都缺少基础。
🎓 小结
Spring Cloud 进阶能力的核心是稳定性治理。微服务不是把应用拆开就结束,而是要处理配置、限流、熔断、追踪、事务和网关治理。真正成熟的微服务系统,必须能在部分服务失败时保持整体可控。