Skip to content

第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接近强一致,依赖框架和代理
TCCTry/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
链路追踪手动传播 traceIdMicrometer 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 进阶能力的核心是稳定性治理。微服务不是把应用拆开就结束,而是要处理配置、限流、熔断、追踪、事务和网关治理。真正成熟的微服务系统,必须能在部分服务失败时保持整体可控。