实战一:订单与库存两个服务的调用链(Feign+降级)

本章打通一条最小调用链:请求经订单服务(order-service)调用库存服务(stock-service)扣减库存,库存不可用时触发 Feign 降级返回兜底。版本锚点同第 01 章:JDK 17/21 + Spring Boot 3.5.x + Spring Cloud 2025.0.x + spring-cloud-alibaba 2025.0.0.x(Nacos 注册发现),以官方文档为准。

依赖与配置

order-service 引入 Nacos 注册发现、OpenFeign 与熔断封装(fallback 由 Resilience4j 实现):

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
# order-service application.yml
spring:
  application:
    name: order-service
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    openfeign:
      circuitbreaker:
        enabled: true      # 开启 Feign 熔断,fallback 才生效

库存服务侧

扣减接口(controller + service,含校验与锁)由库存服务自身实现,写法与普通 Web 接口一致,从略。

订单服务:Feign 接口、降级类与调用

// 1) Feign 接口:声明远程调用;fallback 指定降级类
@FeignClient(name = "stock-service", path = "/stock", fallback = StockFeignFallback.class)
public interface StockFeignClient {
    @PostMapping("/deduct")
    Result<Void> deduct(DeductReqDTO req);
}

// 2) 降级类:必须由 Spring 管理,返回兜底结果
@Component
public class StockFeignFallback implements StockFeignClient {
    @Override
    public Result<Void> deduct(DeductReqDTO req) {
        return Result.fail(503, "库存服务暂不可用,已降级");
    }
}

// 3) 业务层:扣减失败时挂起订单,走异步补偿而非直接失败
@Service
@RequiredArgsConstructor
public class OrderService {
    private final StockFeignClient stockFeignClient;

    public Result<Void> createOrder(OrderReqDTO order) {
        Result<Void> r = stockFeignClient.deduct(toDeductReq(order));
        if (!r.isSuccess()) {
            order.setStatus(OrderStatus.PENDING_STOCK);
            return Result.fail("库存扣减暂不可用,订单已挂起");
        }
        order.setStatus(OrderStatus.CREATED);
        return Result.ok();
    }
}

超时与熔断参数

按 Feign 客户端名分组设置连接/读取超时(键名以官方文档为准);熔断参数同 Resilience4j 章节(窗口 10、失败率 50%、打开 10s)。注意熔断器名与 Feign 客户端名的对应关系随版本有差异,以官方文档为准。

运行与验证

  1. 启动 Nacos、stock-service、order-service。
  2. 正常请求扣库存:两服务日志均有调用记录。
  3. 停掉 stock-service 再请求:返回“库存服务暂不可用,已降级”,order-service 不报错、不堆线程。
  4. 重启 stock-service:实例重新注册后请求自动恢复。

常见问题

  • fallback 不生效:需引入 circuitbreaker 依赖且 enabled=true,降级类被 Spring 管理。
  • 契约不一致:Feign 方法签名与服务端一致,DTO 放公共契约模块。
  • 参数过严:短超时 + 低熔断阈值会让偶发抖动也降级,需结合压测调优。

小结

一条 Feign 调用链 = 注册发现 + 接口契约 + 超时熔断 + 降级兜底;停掉 stock-service 再请求是最低成本的降级演练。

笔记加载中…