Version: Next

OpenFeign 超时控制

OpenFeign 默认超时时间

默认 1 秒钟没有从被调用微服务获取响应,就认为超时

场景设计

  • provider8001 故意写暂停程序
  • consumer-feign-order80PaymentFeignService 中添加 超时方法
  • consumer-feign-order80OrderFeignController 中添加 超时方法
  • 访问 localhost/consumer/payment/feign/timeout,弹出错误页面

provider-payment8001

  • Controller 添加一个 paymentFeignTimeOut 超时方法,里面用线程睡 3 秒,模拟网络超时
模拟网络超时
@GetMapping("/payment/feign/timeout")
public String paymentFeignTimeOut() { // 模拟超时
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
return serverPort;
}

consumer-feign-order80

  • PaymentFeignService 中,添加一个方法,就找上一步所写的 8001 controller 中的超时方法,/payment/feign/timeout
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {
@GetMapping(value = "/payment/get/{id}")
CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
// 调 payment 的超时端口
@GetMapping("/payment/feign/timeout")
String paymentFeignTimeout();
}
  • OrderFeignController 中添加超时方法,通过 paymentFeignService 调用 provider8001 上的超时方法
@RestController
@Slf4j
public class OrderFeignController {
@Resource
private PaymentFeignService paymentFeignService;
@GetMapping("/consumer/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
// 通过 openFeign 去 Eureka 找微服务,调那个微服务的 Controller 接口
return paymentFeignService.getPaymentById(id);
}
// openFeign 转成调用 provider 上的超时方法(Controller)
@GetMapping("/consumer/payment/feign/timeout")
public String paymentFeignTimeOut() {
return paymentFeignService.paymentFeignTimeout();
}
}

测试

  • 运行 70017002
  • 运行 8001,不运行 8002
  • 运行 consumer-feign-order80
  • 访问 http://localhost:8081/payment/feign/timeout
  • 访问 localhost:80/consumer/payment/feign/timeout

访问 http://localhost:8081/payment/feign/timeout

  • 会看到浏览器或POSTMAN等待了3秒,然后得到了响应的微服务端口号 8001

访问 localhost:80/consumer/payment/feign/timeout

响应
{
"timestamp": "2021-01-09T12:02:14.507+0000",
"status": 500,
"error": "Internal Server Error",
"message": "Read timed out executing GET http://CLOUD-PAYMENT-SERVICE/payment/feign/timeout",
...
}
  • 可以看到,报错说超时了,因为 OpenFeign 默认等待对方微服务响应的时间是 1

更改 OpenFeign 超时时间

OpenFeign 里面集成了 Ribbon

  • OpenFeign 的负载均衡、超时控制实际上都是通过 Ribbon 实现的
  • YAML 中通过 Ribbon 配置 即可实现修改超时时间
#设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
#指的是建立连接后从服务器读取到可用资源所用的时间
ReadTimeout: 5000
#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的实际
ConnectTimeout: 5000
  • 重启consumer-feign-order80,再次访问 localhost:80/consumer/payment/feign/timeout
  • 现在可以在等待 3 秒后,得到微服务响应