Feign遠程調(diào)用

代碼參考

Gitee:[https://gitee.com/xn2001/cloudcode/tree/master/06-cloud-feign](https://gitee.com/xn2001/cloudcode/tree/master/06-cloud-feign)

GitHub:[https://github.com/lexinhu/cloudcode/tree/master/06-cloud-feign](https://github.com/lexinhu/cloudcode/tree/master/06-cloud-feign)

我們以前利用 RestTemplate 發(fā)起遠程調(diào)用的代碼:


  • 代碼可讀性差,編程體驗不統(tǒng)一
  • 參數(shù)復雜URL難以維護

Feign 是一個聲明式的 http 客戶端,官方地址:https://github.com/OpenFeign/feign

其作用就是幫助我們優(yōu)雅的實現(xiàn) http 請求的發(fā)送,解決上面提到的問題。

Feign使用

引入依賴

我們在 order-service 引入 feign 依賴:

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

添加注解

在 order-service 啟動類添加注解開啟 Feign

請求接口

在 order-service 中新建一個接口,內(nèi)容如下

package com.xn2001.order.client;

import com.xn2001.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient("userservice")
public interface UserClient {
    @GetMapping("/user/{id}")
    User findById(@PathVariable("id") Long id);
}

@FeignClient("userservice"):其中參數(shù)填寫的是微服務名
@GetMapping("/user/{id}"):其中參數(shù)填寫的是請求路徑
這個客戶端主要是基于 SpringMVC 的注解 @GetMapping 來聲明遠程調(diào)用的信息
Feign 可以幫助我們發(fā)送 http 請求,無需自己使用 RestTemplate 來發(fā)送了。

測試

@Autowired
private UserClient userClient;

public Order queryOrderAndUserById(Long orderId) {
    // 1.查詢訂單
    Order order = orderMapper.findById(orderId);
    // TODO: 2021/8/20 使用feign遠程調(diào)用
    User user = userClient.findById(order.getUserId());
    // 3. 將用戶信息封裝進訂單
    order.setUser(user);
    // 4.返回
    return order;
}

自定義配置

Feign 可以支持很多的自定義配置,如下表所示:



一般情況下,默認值就能滿足我們使用,如果要自定義時,只需要創(chuàng)建自定義的 @Bean 覆蓋默認 Bean 即可。下面以日志為例來演示如何自定義配置。

基于配置文件修改 feign 的日志級別可以針對單個服務:

feign:  
  client:
    config: 
      userservice: # 針對某個微服務的配置
        loggerLevel: FULL #  日志級別 

也可以針對所有服務:

feign:  
  client:
    config: 
      default: # 這里用default就是全局配置,如果是寫服務名稱,則是針對某個微服務的配置
        loggerLevel: FULL #  日志級別 

而日志的級別分為四種:

  • NONE:不記錄任何日志信息,這是默認值。
  • BASIC:僅記錄請求的方法,URL以及響應狀態(tài)碼和執(zhí)行時間
  • HEADERS:在BASIC的基礎上,額外記錄了請求和響應的頭信息
  • FULL:記錄所有請求和響應的明細,包括頭信息、請求體、元數(shù)據(jù)

也可以基于 Java 代碼來修改日志級別,先聲明一個類,然后聲明一個 Logger.Level 的對象


public class DefaultFeignConfiguration  {
    @Bean
    public Logger.Level feignLogLevel(){
        return Logger.Level.BASIC; // 日志級別為BASIC
    }
}

如果要全局生效,將其放到啟動類的 @EnableFeignClients 這個注解中:

@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration .class) 

如果是局部生效,則把它放到對應的 @FeignClient 這個注解中:

@FeignClient(value = "userservice", configuration = DefaultFeignConfiguration .class) 

性能優(yōu)化

Feign 底層發(fā)起 http 請求,依賴于其它的框架。其底層客戶端實現(xiàn)有:

  • URLConnection:默認實現(xiàn),不支持連接池
  • Apache HttpClient :支持連接池
  • OKHttp:支持連接池

因此提高 Feign 性能的主要手段就是使用連接池代替默認的 URLConnection

另外,日志級別應該盡量用 basic/none,可以有效提高性能。

這里我們用 Apache 的HttpClient來演示連接池。

在 order-service 的 pom 文件中引入 HttpClient 依賴

<!--httpClient的依賴 -->
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>

配置連接池

在 order-service 的 application.yml 中添加配置

feign:
  client:
    config:
      default: # default全局的配置
        loggerLevel: BASIC # 日志級別,BASIC就是基本的請求和響應信息
  httpclient:
    enabled: true # 開啟feign對HttpClient的支持
    max-connections: 200 # 最大的連接數(shù)
    max-connections-per-route: 50 # 每個路徑的最大連接數(shù)

最佳實踐

繼承方式

一樣的代碼可以通過繼承來共享:

1)定義一個 API 接口,利用定義方法,并基于 SpringMVC 注解做聲明

2)Feign 客戶端、Controller 都集成該接口

優(yōu)點

  • 簡單
  • 實現(xiàn)了代碼共享

缺點

  • 服務提供方、服務消費方緊耦合
  • 參數(shù)列表中的注解映射并不會繼承,因此 Controller 中必須再次聲明方法、參數(shù)列表、注解

抽取方式

將 FeignClient 抽取為獨立模塊,并且把接口有關的 pojo、默認的 Feign 配置都放到這個模塊中,提供給所有消費者使用。

例如:將 UserClient、User、Feign 的默認配置都抽取到一個 feign-api 包中,所有微服務引用該依賴包,即可直接使用。

接下來我們就用該方法在代碼中實現(xiàn)

首先創(chuàng)建一個 module,命名為 feign-api


在 feign-api 中然后引入依賴

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

order-service中 的 UserClient、User 都復制到 feign-api 項目中

接下來在 order-service 中使用 feign-api

由于我們已經(jīng)將 UserClient、User 放在 fegin-api 中共享了 ,所以可以刪除 order-service 中的 UserClient、User,然后在 order-service 中引入 feign-api

<dependency>
    <groupId>com.xn2001.feign</groupId>
    <artifactId>feign-api</artifactId>
    <version>1.0</version>
</dependency>

修改注解

當定義的 FeignClient 不在 SpringBootApplication 的掃描包范圍下時,這些 FeignClient 就不能使用。

修改 order-service 啟動類上的 @EnableFeignClients 注解

@EnableFeignClients(basePackages = "com.xn2001.feign.clients")
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容