1. 程式人生 > >Spring Cloud Feign 使用總結

Spring Cloud Feign 使用總結

(1)微服務客戶端呼叫服務提供者提供介面實現方式:在Spring Cloud Netflix棧中,各個微服務都是以HTTP介面的形式暴露自身服務的,因此在呼叫遠端服務時就必須使用HTTP客戶端。我們可以使用JDK原生的URLConnection、Apache的Http Client、Netty的非同步HTTP Client, Spring的RestTemplate,國內的OKHTTP 其中,用起來最方便、最優雅的還是要屬Feign了。Feign是一個宣告式的WebService客戶端。使用Feign能讓編寫WebService客戶端更加簡單,它的使用方法是定義一個介面,然後在介面上添加註解,同時也支援JAX-RS標準的註解。Feign也支援可插拔式的編碼器和解碼器。SpringCloud對Feign進行了封裝,使其支援SpringMVC標準註解和HttpMessageConverters。Feign可以與Eureka和Ribbon組合使用以支援負載均衡。
從效能上來說OKHTTP 比Feign 好。(2)Feign實現步驟:a)l引入jar包:spring-cloud-starter-feignb)在啟動類中新增feign註解@EnableFeignClients:c)在service方法中新增“@FeignClinet(“service-provider-name”)”註解,如下圖所示;介面中方法的請求方式(GET/POST)跟介面的保持一致。Spring Cloud應用在啟動時,Feign會掃描標有@FeignClient註解的介面,生成代理,並註冊到Spring容器中。生成代理時Feign會為每個介面方法建立一個RequetTemplate
物件,該物件封裝了HTTP請求需要的全部資訊,請求引數名、請求方法等資訊都是在這個過程中確定的,Feign的模板化就體現在這裡。注意:l  @GetMapping註解不支援;l  @PathVariable註解需要設定value值;l  @RequestParam註解需要設定value值;l  介面引數是複雜的JAVA物件的時候,需要採用POST方式請求,且引數名前需要新增@RequestBody註解,且需要保證介面提供者的介面訪問方式是POST;l  客戶端的呼叫介面的FeignClient介面中,方法名、引數名及引數型別必須和介面方法保持一致;引數名前必須新增@PathVariable或者@RequestParam註解。
l  FeignClient註解中沒有寫其他值,則name值只得是服務提供者的服務名稱;如果定義了url,則feignClient會查詢對應url上的微服務,name此時的值是指feignClient的名稱。name值必須填寫,還可以設定其他的值,如configuration(feignClient配置:預設是SpringMvcContract)的值;l  多個feignCLient類中@FeignClient註解中的name值不能重複,url可以重複;l  服務提供者的介面引數可以寫在請求路徑中,也可不寫在請求路徑中。d)在Controller方法中引入寫好的feignClient介面中的實現方法,即可正常呼叫遠端的介面方法。(3)指定Feign 呼叫特定地址 的服務在功能開發的時候,存在同一個服務多份註冊到eureka 的情況,如果希望呼叫特定的地址服務,那麼可以在@FeignClinet(“service-provider-name”)” 中指定url。@FeignClient註解中的service-provider-name屬性可以是一個任意字串,如果與Eureka組合使用,則service-provider-name應為Eureka中的服務名,Feign用它來建立一個Ribbon負載均衡器。也可以通過url屬性來指定一個地址,可以是完整的URL,也可以是一個主機名。標註了@FeignClient註解的介面,在ApplicationContext中的Bean例項名是這個介面的全限定名,同時這個Bean還有一個別名,為Bean名+FeignClient。(4)覆蓋Feign的預設配置SpringCloud對Feign的封裝中一個核心的概念就是客戶端要有一個名字。每個客戶端隨時可以向遠端服務發起請求,並且每個服務都可以像使用@FeignClient註解一樣指定一個名字。SpringCloud會將所有的@FeignClient組合在一起建立一個新的ApplicationContext,並使用FeignClinetsConfiguration對Clients進行配置。配置中包括編碼器、解碼器和一個feign.Contract。SpringCloud允許你通過configuration屬性完全控制Feign的配置資訊,這些配置比FeignClientsConfiguration優先順序要高:Feign在預設情況下使用的是JDK原生的URLConnection傳送HTTP請求,沒有連線池,但是對每個地址會保持一個長連線,即利用HTTP的persistence connection 。我們可以用Apache的HTTP Client替換Feign原始的http client, 從而獲取連線池、超時時間等與效能息息相關的控制能力。Spring Cloud從Brixtion.SR5版本開始支援這種替換,首先在專案中宣告Apache HTTP Client和feign-httpclient依賴:<!-- 使用Apache HttpClient替換Feign原生httpclient --><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency><dependency><groupId>com.netflix.feign</groupId><artifactId>feign-httpclient</artifactId><version>${feign-httpclient}</version></dependency>然後在application.properties中新增:feign.httpclient.enabled=true(5)Feign的Encoder、Decoder和ErrorDecoderFeign將方法簽名中方法引數物件序列化為請求引數放到HTTP請求中的過程,是由編碼器(Encoder)完成的。同理,將HTTP響應資料反序列化為java物件是由解碼器(Decoder)完成的。預設情況下,Feign會將標有@RequestParam註解的引數轉換成字串新增到URL中,將沒有註解的引數通過Jackson轉換成json放到請求體中。注意,如果在@RequetMapping中的method將請求方式指定為POST,那麼所有未標註解的引數將會被忽略,例如:@RequestMapping(value = "/group/{groupId}", method = RequestMethod.GET)void update(@PathVariable("groupId") Integer groupId, @RequestParam("groupName") String groupName, DataObject obj);
  • 2
此時因為宣告的是GET請求沒有請求體,所以obj引數就會被忽略。在Spring Cloud環境下,Feign的Encoder*只會用來編碼沒有添加註解的引數*。如果你自定義了Encoder, 那麼只有在編碼obj引數時才會呼叫你的Encoder。對於Decoder, 預設會委託給SpringMVC中的MappingJackson2HttpMessageConverter類進行解碼。只有當狀態碼不在200 ~ 300之間時ErrorDecoder才會被呼叫。ErrorDecoder的作用是可以根據HTTP響應資訊返回一個異常,該異常可以在呼叫Feign介面的地方被捕獲到。我們目前就通過ErrorDecoder來使Feign介面丟擲業務異常以供呼叫者處理。(6)Feign中Okhttp應用1、首先在POM中新增如下依賴:<!-- okhttp --><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-okhttp</artifactId></dependency>2、在application.properties中新增配置:#feign use okhttpfeign.httpclient.enabled=falsefeign.okhttp.enabled=true3、如下為啟動服務請求後的日誌記錄,紅色部分為關注重點:[2017-06-27 16:44:35.728] [DEBUG] [restartedMain] o.s.c.e.PropertySourcesPropertyResolver -Found key 'feign.okhttp.enabled' in [applicationConfigurationProperties] with type [String]..........................................................................................................................................................o.s.c.a.ConfigurationClassBeanDefinitionReader -Registering bean definition for @Bean method org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientAutoConfiguration$OkHttpFeignLoadBalancedConfiguration.feignClient()即為在Feign中如何使用Okhttp,非常簡單易用,其自動裝配原始碼在FeignRibbonClientAutoConfiguration中閱讀=================================END===========================360linker是一個分享IT 圈內 市場、技術、產品、運營 等資訊的技術社群。在技術更新換代如此之快的當前,達到高效的的技能的提升,歡迎更多的小夥伴加入。掃描下方二維碼或者新增微信 li_360linker,備註IT。