当前位置:   article > 正文

SpringCloud系列(26)--OpenFeign超时控制_springcloud feign client指定接口设置超时时间

springcloud feign client指定接口设置超时时间

前言:在上一章节中我们简单的介绍了如何使用OprnFeign去调用微服务,因为消费侧和服务侧是两个不同的微服务,这样可能会出现超时的现象,例如服务侧需要3秒处理任何才能返回结果,但消费侧可能2秒就断开连接了,这时就会因为时间差而出现连接超时的问题,而本节内容则是关于如果去对OpenFeign进行超时控制。

1、编写代码模拟连接超时
(1)编写providder-payment8001项目PaymentController类的代码
  1. package com.ken.springcloud.controller;
  2. import com.ken.springcloud.entities.CommonResult;
  3. import com.ken.springcloud.entities.Payment;
  4. import com.ken.springcloud.service.PaymentService;
  5. import lombok.extern.slf4j.Slf4j;
  6. import org.springframework.beans.factory.annotation.Value;
  7. import org.springframework.cloud.client.ServiceInstance;
  8. import org.springframework.cloud.client.discovery.DiscoveryClient;
  9. import org.springframework.web.bind.annotation.*;
  10. import javax.annotation.Resource;
  11. import java.util.List;
  12. import java.util.concurrent.TimeUnit;
  13. @RestController
  14. @Slf4j
  15. public class PaymentController {
  16. @Resource
  17. private PaymentService paymentService;
  18. @Value("${server.port}")
  19. private String serverPort;
  20. @Resource
  21. private DiscoveryClient discoveryClient;
  22. @PostMapping("/payment/insert")
  23. public CommonResult insert(@RequestBody Payment payment) {
  24. int result = paymentService.insert(payment);
  25. log.info("插入结果{}",result);
  26. if(result > 0) {
  27. return new CommonResult(200,"插入数据库成功,提供服务的端口号为" + serverPort,result);
  28. }else {
  29. return new CommonResult(500,"插入数据库失败",result);
  30. }
  31. }
  32. @GetMapping("/payment/get/{id}")
  33. public CommonResult insert(@PathVariable("id") Long id) {
  34. Payment payment = paymentService.getPaymentById(id);
  35. log.info("查询结果{}",payment);
  36. if(payment != null) {
  37. return new CommonResult(200,"查询成功,提供服务的端口号为" + serverPort,payment);
  38. }else {
  39. return new CommonResult(500,"没有对应的数据,查询失败,查询id" + id,payment);
  40. }
  41. }
  42. @GetMapping("/payment/discovery")
  43. public Object discovery() {
  44. //获取eureka内的服务
  45. List<String> services = discoveryClient.getServices();
  46. for (String service : services) {
  47. log.info("***service:" + service);
  48. }
  49. //获取服务名为CLOUD-PAYMENT-SERVICE下的实例
  50. List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
  51. for (ServiceInstance instance : instances) {
  52. log.info(instance.getServiceId()+"\t"+instance.getHost()+"\t"+instance.getPort()+"\t"+instance.getUri());
  53. }
  54. return this.discoveryClient;
  55. }
  56. @GetMapping("/payment/lb")
  57. public String getPaymentLB() {
  58. //返回当前服务的端口号
  59. return serverPort;
  60. }
  61. @GetMapping("/payment/feign/timeout")
  62. public String paymentFeigntimeout() {
  63. try {
  64. TimeUnit.SECONDS.sleep(3);
  65. } catch (InterruptedException e) {
  66. e.printStackTrace();
  67. }
  68. //返回当前服务的端口号
  69. return serverPort;
  70. }
  71. }
(2)编写cloud-consumer-feign-order80项目PaymentFeignService类的代码
  1. package com.ken.springcloud.service;
  2. import com.ken.springcloud.entities.CommonResult;
  3. import org.springframework.cloud.openfeign.FeignClient;
  4. import org.springframework.stereotype.Component;
  5. import org.springframework.web.bind.annotation.GetMapping;
  6. import org.springframework.web.bind.annotation.PathVariable;
  7. @Component
  8. //这里@FeignClient里写的是指定要访问的微服务的名称,表示通过FeignClient去Eureka上面找名称为CLOUD-PAYMENT-SERVICE的微服务的接口
  9. @FeignClient(value = "CLOUD-PAYMENT-SERVICE")
  10. public interface PaymentFeignService {
  11. //指明要调用的CLOUD-PAYMENT-SERVICE的微服务的接口,这里调用的是PaymentController类里的/payment/get/{id}接口
  12. @GetMapping("/payment/get/{id}")
  13. public CommonResult getPaymentById(@PathVariable("id") Long id);
  14. @GetMapping("/payment/feign/timeout")
  15. public String paymentFeigntimeout();
  16. }
(3)编写cloud-consumer-feign-order80项目OrderFeignController的代码
  1. package com.ken.springcloud.controller;
  2. import com.ken.springcloud.entities.CommonResult;
  3. import com.ken.springcloud.entities.Payment;
  4. import com.ken.springcloud.service.PaymentFeignService;
  5. import lombok.extern.slf4j.Slf4j;
  6. import org.springframework.web.bind.annotation.GetMapping;
  7. import org.springframework.web.bind.annotation.PathVariable;
  8. import org.springframework.web.bind.annotation.RestController;
  9. import javax.annotation.Resource;
  10. @Slf4j
  11. @RestController
  12. public class OrderFeignController {
  13. @Resource
  14. private PaymentFeignService paymentFeignService;
  15. @GetMapping("/consumer/payment/get/{id}")
  16. public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
  17. return paymentFeignService.getPaymentById(id);
  18. }
  19. @GetMapping("/payment/feign/timeout")
  20. public String paymentFeigntimeout() {
  21. //客户端一般默认等待1秒钟
  22. return paymentFeignService.paymentFeigntimeout();
  23. }
  24. }

2、测试payment接口是否正常工作

分别启动eureka-server7001、eureka-server7002,然后再启动provider-payment8001,最后再启动cloud-consumer-feign-order80,全部启动完毕后在浏览器的地址栏里输入http://localhost:8001/payment/feign/timeout 并且回车调用接口,最后可以看到接口调用成功并返回8001,这证明provider-payment8001服务工作正常

3、测试通过consumer服务远程调用payment服务

在浏览器地址栏里输入http://localhost/consumer/payment/feign/timeout 并且回车调用接口,这时会显示Read timed out executing GET http://CLOUD-PAYMENT-SERVICE/payment/feign/timeout的错误信息,这是因为Feign客户端默认只等待一秒钟,但是服务端处理需要超过1秒钟,导致Feign客户端不想等待了,直接返回报错,为了避免这样的情况,有时候我们需要设置Feign客户端的超时控制。

效果图:

4、设置Feign客户端的超时时间

修改cloud-consumer-feign-order80项目的application.yml文件(因为OpenFeign集成了Ribbon,所以OpenFeign的超时控制也由最底层的Ribbon来进行限制,所以这里是对Ribbon进行配置)

集成示意图:

application.yml文件

  1. server:
  2. port: 80
  3. eureka:
  4. client:
  5. #表示是否将自己注册进Eureka Server里,默认为true
  6. register-with-eureka: false
  7. service-url:
  8. defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
  9. #设置feign客户端超时时间(OpenFeign默认支持ribbon)
  10. ribbon:
  11. #指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
  12. ReadTimeout: 5000
  13. #指的是建立连接后从服务器读取到可用资源所用的时间
  14. ConnectTimeout: 5000

5、重新测试通过consumer服务远程调用payment服务

重新启动consumer服务,然后重新用浏览器调用http://localhost/consumer/payment/feign/timeout 接口,发现现在并不会再次发生微服务间调用出现连接超时的情况

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/630175
推荐阅读
相关标签
  

闽ICP备14008679号