1 Feign常用配置
搭載着Spring Cloud的順風車,Feign正以席捲之勢成爲使用Spring架構的大大小小互聯網公司發起HTTP調用的首選框架。基於接口的聲明式定義、客戶端負載均衡、斷路器和後備方法(fallback)是Feign相對上一代HTTP調用框架(比如Spring Template,Apache HttpClient)的四大優勢。
類似於Retrofit和OkHttp的關係,Feign實際上是對普通HTTP客戶端的一層封裝,其目的是降低集成成本、提升可靠性。Feign支持三種HTTP客戶端,包括JDK自帶的HttpURLConnection、Apache HttpClient和Square OkHttp,默認使用Apache HttpClient。
- HttpURLConnection:不支持線程池,一般不會選用。
- HttpClient:相比OkHttp,HttpClient並沒有明顯的優勢,可能是因爲使用更廣泛,所以被Feign選爲默認實現。從5.0版本開始才支持HTTP/2。
- OkHttp:開發Android應用的首選HTTP客戶端,支持HTTP/2,通過設置
feign.okhttp.enabled=true
啓用。
Feign提供了兩大類配置屬性來配置上述三種HTTP客戶端,feign.client.*
和feign.httpclient.*
,前者支持按實例進行配置(註解-1),後者全局共享一套配置,包含線程池配置,但隻影響HttpClient和OkHttp,不影響HttpURLConnection,具體關係見下表。
註解-1:所謂按實例進行配置,就是指每個FeignClient實例都可以通過
feign.client.<feignClientName>.*
來單獨進行配置,注意首字母小寫。而feign.client.default.*
表示默認配置。
HTTP客戶端 | 連接超時時間 | 請求超時時間 | 線程存活時間 | 線程池最大連接數(全局) | 線程池最大連接數(單個HOST) |
---|---|---|---|---|---|
HttpURLConnection | feign.client.[default|<feignClientName>].connect-timeout 默認值:10秒 |
feign.client.[default|<feignClientName>].read-timeout 默認值:60秒 |
N/A | N/A | N/A |
HttpClient | feign.httpclient.connection-timeout 默認值:2秒 |
默認值:-1(RequestConfig.Builder.socketTimeout) | feign.httpclient.time-to-live 默認值:900秒 |
feign.httpclient.max-connections 默認值:200 |
feign.httpclient.max-connections-per-route 默認值:50 |
OkHttp | feign.httpclient.connection-timeout 默認值:2秒 |
feign.client.[default|<feignClientName>].read-timeout 默認值:10秒 |
feign.httpclient.time-to-live 默認值:900秒 |
feign.httpclient.max-connections 默認值:200 |
N/A |
從上表可以看到,Feign提供了兩個連接超時配置,HttpURLConnection使用feign.client.[default|<feignClientName>].connect-timeout
,而HttpClient和OkHttp則使用feign.httpclient.connection-timeout
,這一點要尤其注意。
2 啓用Hystrix
通過設置feign.hystrix.enabled=true
可以啓用Feign的斷路器支持(基於Hystrix)。跟Feign一樣,Hystrix也支持按實例進行配置,詳細配置屬性參見官方文檔。
由於Hystrix默認的請求超時時間爲1秒,很容易觸發超時異常,所以往往需要調大。調大超時時間有兩種方式,
- 第一種方式,通過
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds
設置默認超時時間,影響所有請求。 - 第二種方式,如果你不想改變所有請求的超時時間,那麼可以通過
hystrix.command.<HystrixCommandKey>.execution.isolation.thread.timeoutInMilliseconds
單獨設置某個Hystrix Command的超時時間。那麼問題來了,Feign下面,這個Hystrix Command Key到底是什麼呢,是和Feign Client Name一樣嗎?答案是否定的。Feign下面,一個Hystrix Command對應的是Feign Client的一個方法,因此Hystrix Command Key的定義爲<FeignClientName>#<methodName>(<arg1ClassName>,<arg2ClassName>...)
,注意首字母大寫,詳見SetterFactory.Default#create()
方法。
3 小結
不管是Spring還是Spring Cloud,由於整個生態過於龐大,因此即便是官方文檔,也只能勉強覆蓋各個組件的大體框架,一旦深入細節就只能靠開發者自己研讀源碼來尋找答案。就像Linus Torvalds說的,Talk is cheap. Show me the code.