SpringCloud- 第十一篇 Feign+Ribbon

1:概述

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

2:全局配置

ribbon.ConnectTimeout=500 
ribbon.ReadTimeOut=5000

3:指定服務配置

userService.ribbon.ConnectTimeout=500 
userService.ribbon.ReadTimeout=2000

4:重試機制

userService.ribbon.ConnectTimeout=500
userService.ribbon.ReadTimeout=2000
userService.ribbon.OkToRetryOnAllOperations=true
userService.ribbon.MaxAutoRetriesNextServer=2
userService.ribbon.MaxAutoRetries=1
Ribbon的超時與Hystrix的超時是兩個概念。通常須要讓hystrix的超時時間大於Ribbon的超時時間,不然Hystrix命令超時後,直接熔斷,重試機制就沒有任何意義了

5:參數綁定

經常使用綁定參數的方式java

  • @RequestParam 綁定單個請求參數值
  • @PathVariable 綁定URI模板變量值;
  • @RequestHeader 綁定請求頭數據;
  • @RequestBody 綁定請求的內容區數據並能進行自動類型轉換等
注意在定義各參數綁定的時候,@RequestParam和@RequestHeader等能夠指定參數名稱的註解,它們的value值千萬不能少。在spring mvc程序中,這些註解會根據指定參數名來做爲默認值,可是在fegin中綁定參數必須經過value屬性來指明具體的參數名,否則會拋出IllegalStateException異常,value屬性不能爲空。

6:Feign的默認配置

  • 概述

Spring Cloud的Feign的一箇中心概念就是客戶端。 每一個Feign客戶端都是組合的組件的一部分,它們一塊兒工做以按需調用遠程服務器,而且該集合具備將其做爲使用@FeignClient註釋的參數名稱。
SpringCloud使用FeignClientsConfiguration建立一個新的集合,做爲每一個命名客戶端的ApplicationContext(應用上下文),這包含feign.Decoder,feign.Encoder和feign.Contract。spring

  • Spring Cloud Netflix默認爲Feign提供如下bean:

Decoder feignDecoder:ResponseEntityDecoder(其中包含SpringDecoder)
Encoder feignEncoder:SpringEncoder
Logger feignLogger:Slf4jLogger
Contract feignContract:SpringMvcContract
Feign.Builder feignBuilder:HystrixFeign.Builder
Client feignClient:若是Ribbon啓用,則爲LoadBalancerFeignClient,不然將使用默認的feign客戶端。
能夠自定義FeignClientsConfiguration以徹底控制這一系列的配置。apache

7:自定義配置

寫一個自定義配置類,注意不要放到當前ComponentScan的範圍下,示例如:json

@Configuration
public class MyConf {
    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }
}
定義的是new feign.Contract.Default(),全部在UserService接口中只能使用Feign本身的註解url方式,使用Spring MVC的註解就會報錯
寫好配置後,經過設置@FeignClient的configuration來使用,以下:
@FeignClient(value = "userService",configuration=MyConf.class)
能夠爲每一個Feign客戶端都配置本身的默認配置

8: @FeignClient

@FeignClient標籤的經常使用屬性以下:api

  • name(value):指定FeignClient的名稱,若是項目使用了Ribbon,name屬性會做爲微服務的名稱,用於服務發現
  • url: url通常用於調試,能夠手動指定@FeignClient調用的地址
  • configuration: Feign配置類,能夠自定義Feign的Encoder、Decoder、LogLevel、Contract
  • fallback: 定義容錯的處理類,當調用遠程接口失敗或超時時,會調用對應接口的容錯邏輯,fallback指定的類必須實現@FeignClient標記的接口,並使用@Component註解
  • fallbackFactory: 工廠類,用於生成fallback類示例,經過這個屬性咱們能夠實現每一個接口通用的容錯邏輯,減小重複的代碼
  • path: 定義當前FeignClient的統一前綴,添加到Feign訪問服務的訪問路徑上

decode404:當發生http 404錯誤時,若是該字段位true,會調用decoder進行解碼,不然拋出FeignException服務器

  • serviceId屬性如今已被棄用,有利於name屬性。

之前,使用url屬性,不須要name屬性。如今須要使用namemvc

9:Feign和@Primary

9.1:概述

當使用Feign與Hystrix回退時,在同一類型的ApplicationContext中有多個bean。這將致使@Autowired不起做用,由於沒有一個bean標記爲主。
爲了解決這個問題,Spring Cloud Netflix將全部Feign實例標記爲@Primary,因此Spring Framework將知道要注入哪一個bean。在某些狀況下,這多是不可取的。要關閉此行爲,將@FeignClient的primary屬性設置爲false,如:
@FeignClient(name = "hello", primary = false)

10:Feign的HTTP Client

Feign在默認狀況下使用的是JDK原生的URLConnection發送HTTP請求,沒有鏈接池,可是對每一個地址會保持一個長鏈接,即利用HTTP的persistence connection 。
能夠用Apache的HTTP Client替換Feign原始的http client, 從而獲取鏈接池、超時時間等與性能息息相關的控制能力。Spring Cloud從Brixtion.SR5版本開始支持這種替換,首先在項目中聲明Apache HTTP Client和feign-httpclient依賴: 
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>
<dependency>
    <groupId>com.netflix.feign</groupId>
    <artifactId>feign-httpclient</artifactId>
    <version>8.18.0</version>
</dependency>

而後在application.properties中添加: app

feign.httpclient.enabled=true

11: 自定義的Encode、Decode、ErrorDecode

  • Feign將方法簽名中方法參數對象序列化爲請求參數放到HTTP請求中的過程,是由編碼器(Encoder)完成的。同理,將HTTP響應數據反序列化爲java對象是由解碼器(Decoder)完成的。
  • 默認狀況下,Feign會將標有@RequestParam註解的參數轉換成字符串添加到URL中,將沒有註解的參數經過Jackson轉換成json放到請求體中。
  • 在Spring Cloud環境下,Feign的Encoder只會用來編碼沒有添加註解的參數。若是你自定義了Encoder, 那麼只有在編碼沒有註解的參數時纔會調用你的Encoder。
  • 對於Decoder, 默認會委託給SpringMVC中的MappingJackson2HttpMessageConverter類進行解碼。只有當狀態碼不在200 ~ 300之間時ErrorDecoder纔會被調用。ErrorDecoder的做用是能夠根據HTTP響應信息返回一個異常,該異常能夠在調用Feign接口的地方被捕獲到。咱們目前就經過ErrorDecoder來使Feign接口拋出業務異常以供調用者處理。

12: FeignClient工做過程

FeignClient至關於Spring Cloud中的RPC,大體實現的過程以下:負載均衡

1:首先經過@EnableFeignCleints註解開啓FeignCleint
2:根據Feign的規則實現接口,並加@FeignCleint註解
3:程序啓動後,會進行包掃描,掃描全部的@FeignCleint的註解的類,並將這些信息注入到IoC容器中
4:當接口的方法被調用,經過JDK的代理,來生成具體的RequestTemplate
5:RequestTemplate再生成調用的Request
6:Request交給Client去處理,其中Client能夠是HttpUrlConnection、HttpClient也能夠是Okhttp
7:最後Client被封裝到LoadBalanceClient類,這個類結合類Ribbon作到了負載均衡,真正發送請求出去

13:特性繼承

13.1:概述

當使用SpringMVC的註解來綁定服務接口時候,幾乎能夠徹底從服務提供方的Controller中複製操做,構建出相應的服務客戶端綁定接口。既然存在這麼多複製操做,咱們天然須要考慮這部份內容是否能夠獲得進一步的抽象。Spring Cloud Feign中,針對該問題提供了繼承特性來幫助解決這些複製操做,以進一步減小編碼量。

13.2:基本方法

  • 就是把接口提出來,把model提出來,而後provider和client都使用這個工程
  • Provider這邊在Controller中再也不包含以往會定義的映射註解@RequestMapping,而參數的註解定義在重寫的時候自動帶過來了,這個類中,除了要實現接口邏輯以外,只須要增長了@RestController註解使該類成爲一個REST接口類。
  • Consumer這邊直接注入Feign標註的接口,徹底像調用本地接口同樣。

13.3:注意

  • Feign接口只能支持一層繼承,並且不能多繼承
  • 官方不建議在服務器和客戶端之間共享接口,由於它引入了緊耦合,而且實際上並不適用於當前形式的Spring MVC(方法參數映射不被繼承)。

image.png

14:Hystrix配置

14.1: 概述

Spring Cloud Feign中集成了Hystrix,Spring Cloud Feign客戶端的方法都封裝到Hystrix命令中進行服務保護。ide

14.2:全局配置

直接使用它的默認配置前綴hystrix.command.default就能夠進行設置,好比設置全局的超時時間, Hystrix默認的超時時間是1秒:
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000 在對hystrix進行設置以前,須要確認Feign的Hystrix功能是開啓的。

14.3: 禁用hystrix

能夠經過設置feign.hystrix.enabled爲false,或者使用hystrix.command.default.execution.timeout.enabled=false來關閉熔斷功能
若是不想全局地關閉Hystrix支持,而只想針對某個服務客戶端關閉Hystrix支持時,須要經過使用@Scope(「protototype」)註解爲指定的客戶端配置Feign.Builder實例,如:

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

在該服務的Feign接口中引入該配置:

@FeignClient(value = "user-service",configuration = DisableHystrixConfigutation.class) ...

14.4: 指定命令配置

在實際應用中可能會根據實際業務狀況制定出不一樣的配置方案,能夠採用hystrix.command.<commandKey>做爲前綴。而<commandKey>默認狀況下會採用feign客戶端中的方法名做爲標識。須要注意的是,因爲方法名有可能會重複,這個時候相同的方法名的hystrix配置會共用,因此在進行方法與配置的時候須要作好必定的規劃。

14.5: 服務降級配置

Spring Cloud Feign在定義服務客戶端的時候與Spring cloud Ribbon有很大的差異,因爲HystrixCommand定義被封裝起來,沒法經過@HystrixCommand註解的fallback參數那樣來指定具體的服務降級處理方法。Spring Cloud Feign提供了另一種簡單的方式。
方法大體是:定義一個Feign客戶端的服務降級類UserServiceFallback,實現UserService接口,其中每一個重寫方法的實現邏輯均可以用來定義相應的服務降級邏輯;在服務綁定接口中,經過@FeignClient註解的fallback屬性來指定對應的服務降級實現類。

14.6: 請求壓縮

Spring Cloud Feign支持對請求與響應進行GZIP壓縮,以減小通訊過程當中的性能損耗,只須要經過下面的兩個參數設置,就能開啓請求與相應的壓縮功能:

feign.compression.request.enabled=true 
feign.compression.response.enabled=true

同時,還能夠對請求壓縮作一些更細緻的設置,好比下面的配置內容指定壓縮的請求數據類型,並設置了請求壓縮的大小下限,只有超過這個大小的請求才會進行壓縮:

feign.compression.request.enabled=true
feign.compression.request.mime-types=text/xml,application/xml,application/json
feign.compression.request.min-request-size=2048

15:日誌配置

Spring Cloud Feign在構建被@FeignClient註解修飾的服務客戶端時,會爲每個客戶端都建立一個feign.Logger實例,能夠配置logging.level.<feignClient>的參數配置格式來開啓指定feign客戶端的debug日誌,其中<feignClient>爲feign客戶端定義接口的完整路徑,例如:

logging.level.com.cc.springcloud_feign_api.UserService2=debug

注意,只添加該配置還沒法實現對debug日誌的輸出。這是由於feign客戶端默認的Logger.Level對象定義爲NONE級別,該級別不會記錄任何Feign調用過程當中的信息,因此須要調整它的級別,針對全局的日誌級別,能夠在應用主類中加入:

@Bean
Logger.Level feignLoggerLevel(){
    return Logger.Level.FULL;
}

也能夠實現配置類,而後在Feign客戶端來指定配置類以實現不一樣的日誌級別。
對於Feign的Logger級別主要有下面4類,可根據實際須要進行調整使用:

  • none:不記錄任何信息
  • basic:僅記錄請求方法,url以及響應狀態碼和執行時間
  • headers:除了記錄basic級別的信息以外,還會記錄請求和響應的頭信息。
  • FULL:記錄全部請求與響應的明細,包括頭信息,請求體,元數據等。
相關文章
相關標籤/搜索