001-spring boot 2.5.x feign 生产环境使用参考

spring feign 总结

启用

项目中增加依赖

<dependency>
      <groupId>org.springframework.cloudgroupId>
      <artifactId>spring-cloud-starter-openfeignartifactId>
  dependency>
  <dependency>
      <groupId>io.github.openfeigngroupId>
      <artifactId>feign-httpclientartifactId>
      <version>10.12version>
  dependency>

激活配置
启动类添加载 @EnableFeignClients 如下:

@SpringBootApplication
@ComponentScans({@ComponentScan(value = "com.lydemo", excludeFilters = {@ComponentScan.Filter(IgnoreMark.class)})})
@ServletComponentScan("com.lydemo.helloworld.filter")
@EnableFeignClients
public class BootApplication {

基础配置 包括 超时,httpclient,日志配置

# feign配置
feign.httpclient.max-connections=200
feign.httpclient.max-connections-per-route=50
feign.httpclient.connection-timeout=1500
feign.client.config.default.connect-timeout=1500
feign.client.config.default.read-timeout=5000
feign.client.config.default.loggerLevel=BASIC

重试机制

总结:

  1. feign 的调用逻辑 入口: feign.SynchronousMethodHandler#invoke
  2. feign 自身默认 不启用重试 : Retryer.NEVER_RETRY (一般建议不用开启)

配置解析:
通过 org.springframework.cloud.openfeign.FeignClient#configuration 字段注释 发现 默认配置 在 org.springframework.cloud.openfeign.FeignClientsConfiguration

// org.springframework.cloud.openfeign.FeignClientsConfiguration#feignRetryer
@Bean
@ConditionalOnMissingBean
public Retryer feignRetryer() {
  return Retryer.NEVER_RETRY;
}

参考:

  1. https://cloud.tencent.com/developer/article/1083249 (老的 用ribbon)
  2. https://codeleading.com/article/46553623072/ (feign 和 ribbon 重试机制对比)

启用 LoadBalancer 重试

说明

  1. 当不启用 (LoadBalancer 重试) 时候 client 是FeignBlockingLoadBalancerClient ,当启用重试时候 RetryableFeignBlockingLoadBalancerClient ,重试策略是 InterceptorRetryPolicy
  2. 代码执行逻辑 在: org.springframework.cloud.openfeign.loadbalancer.RetryableFeignBlockingLoadBalancerClient#execute (spring boot 配置在org.springframework.cloud.openfeign.loadbalancer.DefaultFeignLoadBalancerConfiguration#feignRetryClient)
  3. 重试 机制 默认也未开启

启用配置
增加如下依赖:


    org.springframework.retry
    spring-retry

添加如下 配置

# loadbalancer 配置
# loadbalancer 配置 (retry.enabled 也会控制 RetryableFeignBlockingLoadBalancerClient 的生成)
spring.cloud.loadbalancer.retry.enabled=true
spring.cloud.loadbalancer.retry.max-retries-on-same-service-instance=0
spring.cloud.loadbalancer.retry.max-retries-on-next-service-instance=1

重试测试

logback 添加如下配置



启动 两个被调用实例 (我启动了helo2 demo 微服务),然后 快速停止其中一个,快速点击调用方实例,出现如下日志:

重试 日志如下

remote.feign.Helo2Client - [log,72] - [Helo2Client#queryUserByName] ---> GET http://HELO2/helo2/queryUserByName?name=lala&sign=2e3817293fc275dbee74bd71ce6eb056 HTTP/1.1
2021-07-25 01:54:29.508 [http-nio-46092-exec-7] DEBUG org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient - [lambda$execute$2,120] - Service instance retrieved from LoadBalancedRetryContext: was null. Reattempting service instance selection
2021-07-25 01:54:29.510 [http-nio-46092-exec-7] DEBUG org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient - [lambda$execute$2,128] - Selected service instance: [EurekaServiceInstance@6b1e9f0 instance = InstanceInfo [instanceId = helo2:192.168.3.6:42379, appName = HELO2, hostName = 192.168.3.6, status = UP, ipAddr = 192.168.3.6, port = 42379, securePort = 443, dataCenterInfo = com.netflix.appinfo.MyDataCenterInfo@2fff1f76]
2021-07-25 01:54:29.510 [http-nio-46092-exec-7] DEBUG org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient - [lambda$execute$2,146] - Using service instance from LoadBalancedRetryContext: [EurekaServiceInstance@6b1e9f0 instance = InstanceInfo [instanceId = helo2:192.168.3.6:42379, appName = HELO2, hostName = 192.168.3.6, status = UP, ipAddr = 192.168.3.6, port = 42379, securePort = 443, dataCenterInfo = com.netflix.appinfo.MyDataCenterInfo@2fff1f76]
2021-07-25 01:54:29.514 [http-nio-46092-exec-7] DEBUG org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient - [lambda$execute$2,120] - Service instance retrieved from LoadBalancedRetryContext: was null. Reattempting service instance selection
2021-07-25 01:54:29.523 [http-nio-46092-exec-7] DEBUG org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient - [lambda$execute$2,128] - Selected service instance: [EurekaServiceInstance@6996f084 instance = InstanceInfo [instanceId = helo2:192.168.3.6:8080, appName = HELO2, hostName = 192.168.3.6, status = UP, ipAddr = 192.168.3.6, port = 8080, securePort = 443, dataCenterInfo = com.netflix.appinfo.MyDataCenterInfo@781923c7]
2021-07-25 01:54:29.523 [http-nio-46092-exec-7] DEBUG org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient - [lambda$execute$2,146] - Using service instance from LoadBalancedRetryContext: [EurekaServiceInstance@6996f084 instance = InstanceInfo [instanceId = helo2:192.168.3.6:8080, appName = HELO2, hostName = 192.168.3.6, status = UP, ipAddr = 192.168.3.6, port = 8080, securePort = 443, dataCenterInfo = com.netflix.appinfo.MyDataCenterInfo@781923c7]
2021-07-25 01:54:29.533 [http-nio-46092-exec-7] DEBUG com.lydemo.helloworld.remote.feign.Helo2Client - [log,72] - [Helo2Client#queryUserByName] <--- HTTP/1.1 200  (25ms)

正常没有重试日志如下:

2021-07-25 02:10:55.381 [http-nio-46092-exec-10] DEBUG com.lydemo.helloworld.remote.feign.Helo2Client - [log,72] - [Helo2Client#queryUserByName] ---> GET http://HELO2/helo2/queryUserByName?name=lala&sign=2e3817293fc275dbee74bd71ce6eb056 HTTP/1.1
2021-07-25 02:10:55.381 [http-nio-46092-exec-10] DEBUG org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient - [lambda$execute$2,120] - Service instance retrieved from LoadBalancedRetryContext: was null. Reattempting service instance selection
2021-07-25 02:10:55.382 [http-nio-46092-exec-10] DEBUG org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient - [lambda$execute$2,128] - Selected service instance: [EurekaServiceInstance@4a2d6add instance = InstanceInfo [instanceId = helo2:192.168.3.6:8080, appName = HELO2, hostName = 192.168.3.6, status = UP, ipAddr = 192.168.3.6, port = 8080, securePort = 443, dataCenterInfo = com.netflix.appinfo.MyDataCenterInfo@781923c7]
2021-07-25 02:10:55.382 [http-nio-46092-exec-10] DEBUG org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient - [lambda$execute$2,146] - Using service instance from LoadBalancedRetryContext: [EurekaServiceInstance@4a2d6add instance = InstanceInfo [instanceId = helo2:192.168.3.6:8080, appName = HELO2, hostName = 192.168.3.6, status = UP, ipAddr = 192.168.3.6, port = 8080, securePort = 443, dataCenterInfo = com.netflix.appinfo.MyDataCenterInfo@781923c7]
2021-07-25 02:10:55.387 [http-nio-46092-exec-10] DEBUG com.lydemo.helloworld.remote.feign.Helo2Client - [log,72] - [Helo2Client#queryUserByName] <--- HTTP/1.1 200  (5ms)

feign circuitbreake

说明

  1. 默认未启用 ,需配置 :feign.circuitbreaker.enabled=false

使用配置

添加如下依赖



   org.springframework.cloud
   spring-cloud-starter-circuitbreaker-resilience4j


配置

feign.circuitbreaker.enabled=true

因为添加了 resilience4j-spring-boot2 所以 resilience4j 可以如下配置:

# resilience4j circuitbreaker 配置
resilience4j.circuitbreaker:
  configs:
    default:
      slidingWindowType: COUNT_BASED
      slidingWindowSize: 100
      minimumNumberOfCalls: 100
      permittedNumberOfCallsInHalfOpenState: 10
      automaticTransitionFromOpenToHalfOpenEnabled: true
      waitIntervalFunctionInOpenState: 60
      failureRateThreshold: 50
      eventConsumerBufferSize: 10
#      recordExceptions:
#        - org.springframework.web.client.HttpServerErrorException
#        - java.io.IOException
#      ignoreExceptions:
#        - java.lang.IllegalStateException
  instances:
    testService:
      baseConfig: default
      slidingWindowSize: 10
      minimumNumberOfCalls: 2
      failureRateThreshold: 1
      recordExceptions:
        - java.lang.Throwable

属性配置优先级高于Java Customizer configuration.

参考:

https://docs.spring.io/spring-cloud-circuitbreaker/docs/current/reference/html/#usage-documentation

你可能感兴趣的:(spring,boot,spring,cloud,spring,spring,boot)