SpringCloud Feign (四)

聲明式服務調用 Spring Cloud Feign

對Spring Cloud Ribbon和Spring Cloud Hystrix在實踐過程當中,這兩個框架的使用幾乎是同時出現的,Spring Cloud Feign就是一個更高層次的封裝來整合這兩個基礎工具以簡化開發。它基於Netflix Feign實現,除了提供這二者的強大功能以外,它還提供了一種聲明式的Web服務客戶端定義的方式。Spring Cloud Feign在RestTemplate的封裝基礎上作了進一步封裝,由它來幫助定義和實現依賴服務接口的定義,在Spring Cloud Feign的實現下,只需建立一個接口並用註解的方式來配置它,便可完成對服務提供方接口的綁定。Spring Cloud Feign具有可插拔的註解支持,包括Feign註解和JAX-RS註解,爲了適應Spring用戶,它在Netflix Feign基礎上擴展了對Spring MVC註解的支持。java

1. 快速集成 Spring Cloud Feign

基礎服務搭建

  • eureka-server工程:服務註冊中心spring

  • hello-service工程:服務提供者app

  • Spring Cloud Feign Client服務搭建負載均衡

    1. 建立Spring Boot 工程 feign-consumer框架

    2. 添加依賴: spring-cloud-starter-eureka-server, spring-cloud-starter-feignide

    3. 配置指定服務註冊中心,並定義自身服務名函數

    4. 使用@EnableFeignClients開啓Spring Cloud Feign 的支持功能工具

    5. 定義HelloClient接口,使用@FeignClient註解指定服務名來綁定服務,使用SpringMVC註解綁定具體該服務提供的REST接口ui

      @FeignClient("hello-service")
      public interface HelloClient {
          
          @RequestMapping("/hello")
          String hello();
      }
    6. 在須要調用的地方使用@Autowired注入HelloClient實例,並調用該指定服務接口來向該服務發起/hello接口的調用prototype

2. 參數綁定

  • 設置Request Header

    經過設置Feign攔截器統一設置token,須要實現Feign提供的一個接口 RequestInterceptor

    @Configuration
    public class FeignRequestInterceptor implements RequestInterceptor {
        
        @Override
        public void apply(RequestTemplate requestTemplate) {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (null != attributes) {
                HttpServletRequest request = attributes.getRequest();
                if (null != request) {
                	//添加token
                    requestTemplate.header("Authorization", request.getHeader("Authorization"));
                }
            }
        }
    }

    自定義Feign配置覆蓋默認配置

    @Configuration
    public class FeignConfiguration {
        
        @Bean
        public FeignRequestInterceptor feignRequestInterceptor() {
            return new FeignRequestInterceptor();
        }
        
        // 超時重試
        @Bean
        public Retryer feignRetryer() {
            return new Retryer.Default(100, 1000, 5);
        }
    }

    在定義各參數綁定時,@RequestParam, @PathVariable等能夠指定參數名稱的註解,value屬性不能缺乏,在Feign中綁定參數必須經過value屬性指明具體的參數名,不然拋出 IllegalStateException異常。

  • 接收對象類型請求響應體

    接收對象必須有默認的構造函數即無參構造器,不然Spring Cloud Feign 根據 JSON 字符串轉換對象時拋出異常。

3. 配置

3.1 Ribbon配置

Spring Cloud Feign客戶端負載均衡經過Spring Cloud Ribbon實現,能夠直接經過配置Ribbon客戶端的方式自定義各個服務客戶端的調用參數。

  • 全局配置

    使用 ribbon.<key>=<value>的方式設置ribbon的各項參數,如

    ribbon.ConnectTimeout=500
    ribbon.ReadTimeout=5000
  • 指定服務配置

    針對各個服務客戶端進行個性化配置的方式與全局配置類似,使用<client>.ribbon.<key>=<value>的方式設置。client能夠使用@FeignClient註解中的name或value屬性值來設置對應的ribbon參數,如

    HELLO-SERVICE.ribbon.ConnectTiomeout=500
    HELLO-SERVICE.ribbon.ReadTimeout=5000
    HELLO-SERVICE.ribbon.OkToRetryOnAllOperations=true
    HELLO-SERVICE.ribbon.MaxAutoRetriesNextServer=2  // 嘗試更換實例次數
    HELLO-SERVICE.ribbon.MaxAutoRetries=1  // 嘗試訪問首選實例次數
  • 重試機制

    Spring Cloud Feign中默認實現了請求的重試機制,上面對於HELLO-SERVICE客戶端的配置就是對請求超時及重試機制配置的詳情。

3.2 Hystrix配置

Spring Cloud Feign 還引入了服務保護與容錯的工具Hystrix。默認狀況Spring Cloud Feign會爲全部Feign客戶端的方法都封裝到Hystrix命令中進行服務保護。

  • 全局配置

    使用hystrix.command.default.<key>=<value>的方式配置hystrix各項參數,如

    hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
  • 禁用 Hystrix

    1. 全局禁用

      feign.hystrix.enabled=false
    2. 針對指定服務禁用Hystrix

      構建關閉Hystrix配置類

      @Configuration
      public class DisableHystrixConfiguration {
          
          @Bean
          @Scope("prototype")
          public Feign.Builder feignBuilder() {
              return Feign.builder();
          }
      }

      @FeignClient註解中經過configuration參數引入配置類

      @FeignClient(name = "HELLO-SERVICE", configuration = DisableHystrixConfiguration.class)
      public interface HelliClient {
  • 指定命令配置

    使用hystrix.command. 做爲前綴, 默認狀況下采用Feign客戶端中的方法名做爲標識。

    如配置/hello接口的熔斷超時時間:

    hystrix.command.hello.execution.isolation.thread.timeoutInMilliseconds=5000
  • 服務降級配置

    1. 爲Feign客戶端的定義接口HelloService實現一個具體的實現類HelloServiceFallback

      @Component
      public class HelloServiceFallback implements HelloService {
    2. 在服務綁定接口中經過@FeignClient註解的fallback屬性來指定對應的服務降級實現類

      @FeignClient(name="HELLO-SERVICE", fallback=HelloServiceFallback.class)
      public interface HelloService {
相關文章
相關標籤/搜索