天天看點

SpringCloud Feign 聲明式服務調用

服務調用有2種方式:rest、rpc,springcloud使用RestTemplate實作rest調用,還可以使用feign進行聲明式的遠端http服務調用,所謂聲明式就是通過服務接口來調用,和rpc相似。

使用feign進行服務調用

feign是一種服務調用方式,自然是在消費者中使用的

1、建立時勾選Spring Cloud Routing -> OpenFeign,或者手動添加依賴

<dependency>         <groupId>org.springframework.cloud</groupId>         <artifactId>spring-cloud-starter-openfeign</artifactId>     </dependency>           

2、引導類上加 @EnableFeignClients

//如果不指定basePackages,預設會掃描所有的包     @EnableFeignClients(basePackages = "com.chy.mall.feignclient")           

在引導類上加@EnableXxx的,在啟動時會掃描相關注解。

3、建立包feignclient用來存放feign服務調用的接口

@FeignClient("order-service")  //指定要調用的服務名稱。feign也内置了ribbon,會自動實作負載均衡     @RequestMapping("/order")     public interface OrderServiceFeignClient {         @GetMapping("/list/{user_id}")  //指定位址         List<Order> findOrdersByUserId(@PathVariable("user_id") Integer userId);      }           

可以使用springmvc的注解綁定參數。

@FeignClient(name=“order-service”),name的别名是value,也可以寫成@FeignClient(value=“order-service”),注解特性可以預設value。

4、service

@Service     public class UserService {       @Autowired         private OrderServiceFeignClient orderServiceFeignClient;  //注入要使用的Feign接口         public List<Order> findOrdersById(Integer userId){             //通過Feign接口進行服務調用             return orderServiceFeignClient.findOrdersByUserId(userId);         }     }           

feign的常用配置項

以feign的日志配置為例,一般的日志直接在logging.level中配置即可,feign的日志配置方式有些不同,就算把日志級别設定為debug,feign預設也不會輸出任何日志。

feign有自己的日志級别

  • NONE:預設值,不列印任何日志
  • BASIC: 隻列印請求方法、url、響應狀态碼、執行時間
  • HEADERS:在BASIC的基礎上,會列印請求、響應的header
  • FULL:列印請求、響應的header、body、中繼資料,可以看到提供者傳回的資料。

生産環境一般用BASIC,輸出日志少,性能好;開發環境一般用FULL,友善調試。

代碼配置方式

yml

logging:       level:         root: info         #feign列印日志的前提是feign接口的日志級别是debug,因為feign輸出的日志是debug級别         com.chy.mall.feignclient: debug           

配置類 config.FeignClientConfig

import feign.Logger;     import org.springframework.context.annotation.Bean;     /**      * 定義feign接口的日志級别      * 不要加@Configuration      */     public class FeignClientConfig {         @Bean         public Logger.Level level(){             return Logger.Level.FULL;         }     }           

引導類

//指定feign的配置類     @EnableFeignClients(basePackages = "com.chy.mall.feignclient", defaultConfiguration = FeignClientConfig.class)     //上面是全局配置,給所有的feign接口指定,也可以分别給feign接口指定     //@FeignClient("order-service", configuration = FeignClientConfig.class)           

步驟也繁瑣,不推薦。

屬性配置方式(推薦)

logging:       level:         root: info         #将feign接口的日志級别設定為debug,因為feign輸出的日志是debug級别         com.chy.mall.feignclient: debug     feign:       client:         config:           #全局配置,指定所有feign服務調用的日志級别           default:             loggerLevel: full            #也可以分别配置各個服務調用的     #      order-server:     #        loggerLevel: full     #      msg-server:     #        loggerLevel: full           

無需其它配置。

除了loggerLevel,feign的其它常用配置項如下

  • connectTimeout: 10000  連接配接逾時時間
  • readTimeout: 10000  讀取逾時時間

feign的繼承特性

提供者提供接口,消費者中有要調用的接口聲明,提供者修改了接口的映射位址、形參表、傳回值類型,比如傳回類型是實體類,現在需求變了,這個實體類要增删一些成員變量,提供者修改接口後,消費者也要同步修改,接口維護起來很麻煩。

feign的繼承特性:将要服務之間要調用的接口、涉及的實體類提出來,單獨寫成一個子產品,打成jar包在提供者、消費者中引入,然後提供者的controller實作接口,消費者的feign接口繼承接口(無需再進行聲明)。更改接口時,要稍微好維護一些。

官方不推薦使用feign的繼承特性,因為會使服務耦合在一起,但實際使用的公司也不少。

傳遞多個參數

restful适合參數少的情況,如果參數較多,可以使用以下幾種方式

  • feign接口、提供者的接口都使用 @RequestParam + 多個參數
  • feign接口、提供者的接口都使用 @RequestParam + Map<String,Object>
  • 提供者的接口用實體類聲明參數,feign接口用 @SpringQueryMap + 實體類

第一二種都支援feign的繼承特性,第三種不支援。

不建議使用Map接收參數,需要自己轉換參數的資料類型,麻煩、易出錯。

如果把@SpringQueryMap換成@RequestParam,可以調用服務,但傳過去的實體的成員變量都是null。

脫離ribbon使用feign

ribbon是從自己的注冊中心擷取節點清單,如果是通過第三方的網關調用他們的服務,可以用HttpClient發起請求,也可以用feign發起請求,此時feign是脫離ribbon使用的。

//url指定請求位址,value指定服務名     @FeignClient(value = "xxx-server",url = "http://www.xxx.com/xxx")           

服務名是必需的,如果不指定服務名,啟動不了應用。在指定了url的情況下,服務名可以随便寫一個。

feign與RestTemplate的對比

feign 僞裝、假裝,feign隻是僞rpc調用,實際使用的還是RestTemplate,使用的協定還是http。

  • feign性能要低于直接使用RestTemplate。feign是将RestTemplate包裝為feign接口,生成動态代理,通過代理進行操作,有額外的開銷,拉低了性能。
  • feign讓代碼可讀性更好、易于維護。服務調用接口聲明都聚集在一起,友善檢視、修改;接口改動時隻需修改feignclient包下的feign接口,無需找到所有的服務調用處,維護友善。

一般都是使用feign。

feign性能優化之配置連接配接池

feign預設使用urlconnection發起請求,不使用連接配接池;feign也支援用httpclient發起請求,可以使用feign-httpclient、okhttp等jar包提供的httpclient連接配接池。

httpclient

<dependency>         <groupId>io.github.openfeign</groupId>         <artifactId>feign-httpclient</artifactId>     </dependency>           
feign:       #配置httpclient連接配接池       httpclient:       	#預設true         enabled: true         #feign連接配接池的最大連接配接數         max-connections: 200         #feign連接配接池單個url的最大連接配接數         max-connections-per-route: 50           

這些數值都是預設值,根據壓測結果進行修改

okhttp

feign:       okhttp:       	#預設false         enabled: true       #配置httpclient連接配接池       httpclient:         #feign連接配接池的最大連接配接數         max-connections: 200         #feign連接配接池單個url的最大連接配接數         max-connections-per-route: 50           

當然,也可以使用其它提供了httpclient連接配接池的jar包,但需要指定jar包的<version>。

繼續閱讀