上一節( 跟我學Spring Cloud(Finchley版)-09-Feign )講了Feign的入門姿式並深刻對比了RestTemplate,本節來深刻探討Feign的高級特性。總的來講,Feign是一個相對簡單的組件,但細節仍是比較多的,一不當心就可能入坑,注意點我會以WARINING的形式標記出來,便於讀者查閱。java
Spring Cloud Netflix provides the following beans by default for feign (BeanType
beanName: ClassName
):git
Decoder
feignDecoder: ResponseEntityDecoder
(which wraps a SpringDecoder
)Encoder
feignEncoder: SpringEncoder
Logger
feignLogger: Slf4jLogger
Contract
feignContract: SpringMvcContract
Feign.Builder
feignBuilder: HystrixFeign.Builder
Client
feignClient: if Ribbon is enabled it is a LoadBalancerFeignClient
, otherwise the default feign client is used.The OkHttpClient and ApacheHttpClient feign clients can be used by setting feign.okhttp.enabled
orfeign.httpclient.enabled
to true
, respectively, and having them on the classpath.github
Spring Cloud Netflix does not provide the following beans by default for feign, but still looks up beans of these types from the application context to create the feign client:spring
Logger.Level
Retryer
ErrorDecoder
Request.Options
Collection<RequestInterceptor>
SetterFactory
默認Feign是不打印任何日誌的,下面咱們來開啓Feign的日誌,Feign有四種日誌級別:json
插科打諢 & 惡意揣測app
跟我學Spring Cloud(Finchley版)-09-Feign說過,Feign的性能中等,可能官方對本身的性能也是知道的,索性所有關閉日誌了,哈哈ide
將前文的Feign Client修改成以下:性能
@FeignClient(name = "microservice-provider-user", configuration = UserFeignConfig.class) public interface UserFeignClient { @GetMapping("/users/{id}") User findById(@PathVariable("id") Long id); } /** * 該Feign Client的配置類,注意: * 1. 該類能夠獨立出去; * 2. 該類上也可添加@Configuration聲明是一個配置類; * 配置類上也可添加@Configuration註解,聲明這是一個配置類; * 但此時千萬別將該放置在主應用程序上下文@ComponentScan所掃描的包中, * 不然,該配置將會被全部Feign Client共享,沒法實現細粒度配置! * 我的建議:像我同樣,不加@Configuration註解 * * @author zhouli */ class UserFeignConfig { @Bean public Logger.Level logger() { return Logger.Level.FULL; } }
如代碼所示,使用註解@FeignClient
的configuration
屬性,指定一個類,便可實現Feign配置自定義。測試
TIPSui
- 本例簡單起見,直接弄了個外部類做爲配置類
UserFeignConfig
,讀者也可將該類獨立出去做爲一個public class
。WARNING
- 配置類上也可添加
@Configuraiton
註解,聲明這是一個配置類;但此時千萬別將該放置在主應用程序上下文@ComponentScan
所掃描的包中,不然,該配置將會被全部Feign Client共享(至關於變成了通用配置,其實本質仍是Spring父子上下文掃描包重疊致使的問題),沒法實現細粒度配置!- 我的建議:像我同樣,不加@Configuration註解,免得進坑。
聯想記憶
還記得Ribbon如何使用Java代碼自定義配置嗎?Ribbon使用Java代碼自定義配置時也必須防止配置類在
@ComponentScan
上下文內,詳見: 跟我學Spring Cloud(Finchley版)-08-Ribbon深刻
在application.yml
中添加如下內容,將該Feign接口的日誌級別設置爲DEBUG:
logging: level: com.itmuch.cloud.study.user.feign.UserFeignClient: debug
此時,當該Feign Client的方法被調用時,將會打印相似以下的日誌:
2019-01-10 22:14:10.611 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient : [UserFeignClient#findById] ---> GET http://microservice-provider-user/users/1 HTTP/1.1 2019-01-10 22:14:10.611 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient : [UserFeignClient#findById] ---> END HTTP (0-byte body) 2019-01-10 22:14:10.623 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient : [UserFeignClient#findById] <--- HTTP/1.1 200 (11ms) 2019-01-10 22:14:10.623 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient : [UserFeignClient#findById] content-type: application/json;charset=UTF-8 2019-01-10 22:14:10.623 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient : [UserFeignClient#findById] date: Thu, 10 Jan 2019 14:14:10 GMT 2019-01-10 22:14:10.623 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient : [UserFeignClient#findById] transfer-encoding: chunked 2019-01-10 22:14:10.623 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient : [UserFeignClient#findById] 2019-01-10 22:14:10.624 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient : [UserFeignClient#findById] {"id":1,"username":"account1","name":"張三","age":20,"balance":100.00} 2019-01-10 22:14:10.624 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient : [UserFeignClient#findById] <--- END HTTP (72-byte body)
從Spring Cloud Edgware開始,Feign支持使用屬性自定義Feign。對於一個指定名稱的Feign Client(例如該Feign Client的名稱爲feignName
),Feign支持以下配置項:
feign: client: config: feignName: connectTimeout: 5000 # 至關於Request.Options readTimeout: 5000 # 至關於Request.Options # 配置Feign的日誌級別,至關於代碼配置方式中的Logger loggerLevel: full # Feign的錯誤解X碼X器,至關於代碼配置方式中的ErrorDecoder errorDecoder: com.example.SimpleErrorDecoder # 配置重試,至關於代碼配置方式中的Retryer retryer: com.example.SimpleRetryer # 配置攔截器,至關於代碼配置方式中的RequestInterceptor requestInterceptors: - com.example.FooRequestInterceptor - com.example.BarRequestInterceptor decode404: false
TIPS
我的並不建議配置retryer,Spring Cloud Camden以及以後的版本中,Spring Cloud關閉了Feign的重試,而是使用Ribbon的重試。若是本身再定義Feign的重試後,那麼可能會形成重試特性的混亂。筆者已在https://github.com/spring-cloud/spring-cloud-netflix/issues/2330 提出該問題。
要想用屬性配置方式來達到上面Java代碼方式的效果,只需在application.yml
中添加以下內容便可:
feign: client: config: microservice-provider-user: loggerLevel: full logging: level: com.itmuch.cloud.study.user.feign.UserFeignClient: debug
上面討論瞭如何配置特定名稱的Feign Client,那麼若是想爲全部的Feign Client都進行配置,該怎麼辦呢?咱們知道,@EnableFeignClients
註解上有個defaultConfiguration
屬性,咱們能夠將默認配置寫成一個類,而後用defaultConfiguration
來引用,例如:
@EnableFeignClients(defaultConfiguration = DefaultRibbonConfig.class)
若是想使用配置屬性的方式,只需使用相似以下的寫法便可。
feign: client: config: default: connectTimeout: 5000 readTimeout: 5000 loggerLevel: basic
若是你不當心又使用了Java代碼配置Feign,同時又使用了配置屬性配置Feign,那麼使用配置屬性的優先級更高。配置屬性配置的方式將會覆蓋Java代碼配置。若是你想修改代碼配置方式的優先級,可以使用以下屬性:feign.client.default-to-properties=false
。
一些場景下,咱們可能須要對請求或響應進行壓縮,此時可以使用如下屬性啓用Feign的壓縮功能。
feign.compression.request.enabled=true feign.compression.response.enabled=true
對於請求的壓縮,Feign還提供了更爲詳細的設置,例如:
feign.compression.request.enabled=true feign.compression.request.mime-types=text/xml,application/xml,application/json feign.compression.request.min-request-size=2048
其中,feign.compression.request.mime-types
用於支持的媒體類型列表,默認是text/xml、application/xml以及application/json。
feign.compression.request.min-request-size
用於設置請求的最小閾值,默認是2048。
比較重要,業界對繼承特性見解很是不同,喜歡的特別喜歡,討厭的特別討厭(例如我)。將以番外形式體現,並對比二者優缺點,以及最佳實踐,明天或後天更新,敬請期待。
Feign其餘特性我已經寫了不少了,知識體系已經完備了。懶得再在這個系列裏湊字數,這不是個人風格,直接貼地址吧:
http://www.itmuch.com/spring-cloud/finchley-10/