openFeign常用注解及超时时间规则详解

Feign可以把Rest请求进行封装,将远程调用的请求封装成本地请求的方式,不需要再手动拼接url和路径
1请求路径
2请求参数
3请求方式
4返回结果
我们使用注解的方式将此四项参数提供给Feign,Feign即可帮我们自动完成一次远程请求
注解:
主类上方加入:

  1. @EnableFeignClients

新建一个接口,并使用注解方式提供4项参数:

  1. @FeignClient("user-service")//提供请求地址
  2. public interface UserClient {
  3. @GetMapping("user/{id}")//提供请求路径及参数
  4. String queryById(@PathVariable("id") Long id);//提供请求方式及返回结果
  5. }

服务调用代码的改变:
原来的代码:

  1. @RestController
  2. @RequestMapping("consumer")
  3. @DefaultProperties(defaultFallback = "fallBack")
  4. public class UserController {
  5. @Autowired
  6. private RestTemplate restTemplate;
  7. @GetMapping("{id}")
  8. @HystrixCommand
  9. public String queryById(@PathVariable("id") Long id){
  10. String url = "http://user-server/user/"+id;
  11. String user = restTemplate.getForObject(url, String.class);
  12. return user;
  13. }
  14. public String fallBack(Long id){
  15. return "服务太拥挤了,请稍后再试!";
  16. }
  17. }

改为:

  1. @RestController
  2. @RequestMapping("consumer")
  3. @DefaultProperties(defaultFallback = "fallBack")
  4. public class UserController {
  5. @Autowired
  6. private UserClient userClient; //注意这里不再有RestTemplate了
  7. @GetMapping("{id}")
  8. @HystrixCommand
  9. public String queryById(@PathVariable("id") Long id){
  10. return String user = userClient.queryById(id); //此处看起来就是本地的调用了一个方法
  11. }
  12. public String fallBack(Long id){
  13. return "服务太拥挤了,请稍后再试!";
  14. }
  15. }

主类:

  1. @SpringCloudApplication
  2. public class ConsumerApplication {
  3. @Bean
  4. @LoadBalanced
  5. public RestTemplate restTemplate(){
  6. return new RestTemplate();
  7. }
  8. public static void main(String[] args) {
  9. SpringApplication.run(ConsumerApplication.class, args);
  10. }
  11. }

改为:

  1. @EnableFeignClients
  2. @SpringCloudApplication
  3. public class ConsumerApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(ConsumerApplication.class, args);
  6. }
  7. }

feign日志

除此之外Feign还支持请求压缩和日志级别,此处不详述
首先需要配置Feign的打印日志的级别。

  1. @Configuration
  2. public class FeignConfig {
  3. /**
  4. * NONE:默认的,不显示任何日志
  5. * BASIC:仅记录请求方法、URL、响应状态码及执行时间
  6. * HEADERS:出了BASIC中定义的信息之外,还有请求和响应的头信息
  7. * FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元素
  8. */
  9. @Bean
  10. public Logger.Level feginLoggerLevel() {
  11. return Logger.Level.FULL;
  12. }
  13. }

第二步,需要设置打印的Feign接口。Feign为每个客户端创建一个logger。默认情况下,logger的名称是Feigh接口的完整类名。需要注意的是,Feign的日志打印只会对DEBUG级别做出响应

  1. #与server同级
  2. logging:
  3. level:
  4. com.yehongzhi.springcloud.consumer.feign.ProviderClient: debug

设置完成后,控制台可以看到详细的请求信息。
img

OpenFeign超时时长设置及详解

概念明确:
1 hystrix可配置的部分

  1. hystrix.command.default.execution.timeout.enable=true //为false则超时控制有ribbon控制,为true则hystrix超时和ribbon超时都是用,但是谁小谁生效,默认为truehystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000//熔断器的超时时长默认1秒,最常修改的参数
  2. circuitBreaker.requestVolumeThreshold=20 //触发熔断的最小请求次数,默认为20
  3. circuitBreaker.sleepWindowInMilliseconds=5000 //休眠时长,默认为5秒
  4. circuitBreaker.errorThresholdPercentage=50 //触发熔断的失败请求最小占比,默认50%

2 ribbon的可配置部分

  1. ribbon.ReadTimeout=1000 //处理请求的超时时间,默认为1秒
  2. ribbon.ConnectTimeout=1000 //连接建立的超时时长,默认1秒
  3. ribbon.MaxAutoRetries=1 //同一台实例的最大重试次数,但是不包括首次调用,默认为1次
  4. ribbon.MaxAutoRetriesNextServer=0 //重试负载均衡其他实例的最大重试次数,不包括首次调用,默认为0次ribbon.OkToRetryOnAllOperations=false //是否对所有操作都重试,默认false

3 Feign的可配置部分

  1. feign.hystrix.enabled=false //Feign是否启用断路器,默认为false
  2. feign.client.config.default.connectTimeout=10000 //Feign的连接建立超时时间,默认为10秒
  3. feign.client.config.default.readTimeout=60000 //Feign的请求处理超时时间,默认为60feign.client.config.default.retryer=feign.Retryer.Default //Feign使用默认的超时配置,在该类源码中可见,默认单次请求最大时长1秒,重试5次

另外以上各种超时配置,如果都存在,则时间小的配置生效
好的,现在来说Feign的超时时长设置:
1 Feign的默认配置,是不启用hystrix,并且Feign的底层是调用ribbon来实现负载均衡的,所以为了不和ribbon的重试机制冲突因此也不会启用重试机制
因此配置Feign是必须要做的就是

  1. feign.hystrix.enabled=true //开启Feign的hystrix,这样配置文件中的hystrix的配置才会生效,否则依然是默认的规则

之后设置hystrix的相关配置才可以在Feign中生效,因为Feign也调用了hystrix
2 ribbon和hystrix的配置
因为hystrix的超时时长,默认为1秒,太短了!因此我们一般一定会设置hystrix的超时时长
在上面启用了Feign的hystrix开关后,配置hystrix超时时长

  1. execution.isolation.thread.timeoutInMilliseconds=10000 //这里设置了10秒

然后看ribbon的超时设置:
ribbon的超时设置无非2个:处理超时和连接超时,默认为1秒和1秒
但是,ribbon是有默认重试的,也是2个:统一实例的重试次数和负载均衡的不同实例的重试次数,默认为1次和0次
也就是说,在同一个实例上建立连接如果失败可以重试1次,处理请求如果失败可以重试1次,但是不包括首次调用,即:实际ribbon的超时时间是 1秒×2+1秒×2,即4秒
之后是,但是上面设置了hystrix超时为10秒,因此ribbon超时优先生效
最后是1个是否对所有操作重试的开关,默认为false,这里解释下什么是所有操作:
即:为false是,GET请求不论是连接失败还是处理失败都会重试,而对于非GET请求只对连接失败进行重试

结论

因此得出结论,在使用了Feign的情况下需先开启断路器支持,之后配置hystrix的timeoutInMillisecond大于ribbon的 ( ConnectTimeout + ReadTimeout ) × 2即可
也就是说以后以后的配置中常用的配置项就是
1 开启Feign的hystrix开关
2 hystrix超时时长
3 配置ribbon的ConnectTimeout时长
4 配置ribbon的ReadTimeout 时长