🏆 作者簡介,愚公搬代碼
🏆《頭銜》:華為云特約編輯,華為云云享專家,華為開發者專家,華為產品云測專家,CSDN博客專家,阿里云專家博主,阿里云簽約作者,騰訊云優秀博主,騰訊云內容共創官,掘金優秀博主,51CTO博客專家等。
🏆《近期榮譽》:2022年CSDN博客之星TOP2,2022年華為云十佳博主等。
🏆《博客內容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鴻蒙、Linux、物聯網、網絡安全、大數據、人工智能、U3D游戲、小程序等相關領域知識。
🏆🎉歡迎 👍點贊?評論?收藏
文章目錄
- 🚀前言
- 🚀一、Feign遠程調用
- 🔎1.Feign替代RestTemplate
- 🦋1.1 引入依賴
- 🦋1.2 添加注解
- 🦋1.3 編寫Feign的客戶端
- 🦋1.4 測試
- 🔎2.自定義配置
- 🦋2.1 配置文件方式
- 🦋2.2 Java代碼方式
- 🔎3.Feign使用優化
- 🔎4.最佳實踐
- 🦋4.1 繼承方式
- 🦋4.2 抽取方式
- 🦋4.3 實現基于抽取的最佳實踐
- ??4.3.1 抽取
- ??4.3.2 在order-service中使用feign-api
- ??4.3.3 重啟測試
- 🚀感謝:給讀者的一封信
🚀前言
微服務架構中,不同的服務之間需要相互通信來完成任務。其中一種常見的通信方式是遠程調用。遠程調用是指在不同的服務之間進行函數調用,而這些服務運行在不同的計算機、進程或容器中。
常見的微服務遠程調用方式有:
-
REST API:基于 HTTP 協議實現,通過發送 HTTP 請求來調用服務,并通過 JSON 或 XML 等格式傳遞數據。
-
gRPC:基于 Google 的開源 RPC 框架實現,支持多種語言,并使用 Protocol Buffers 作為數據格式,提供了更高效的數據傳輸和更簡單的接口定義。
-
AMQP:基于消息隊列實現,使用消息進行服務之間的通信,可保證消息的可靠性和可恢復性。
-
Apache Thrift:開源的跨語言 RPC 框架,可生成多種語言的代碼庫,并支持多種數據傳輸協議,如 TCP、HTTP、ZLIB、FRAMED 等。
-
Socket:原始的方式,通過套接字進行通信,在性能上有一定優勢,但需要自行處理數據格式和協議。
🚀一、Feign遠程調用
用RestTemplate發起遠程調用的代碼:
存在下面的問題:
- 代碼可讀性差,編程體驗不統一
- 參數復雜URL難以維護
Feign是一個聲明式的http客戶端,官方地址:https://github.com/OpenFeign/feign
其作用就是幫助我們優雅的實現http請求的發送,解決上面提到的問題。
🔎1.Feign替代RestTemplate
🦋1.1 引入依賴
我們在order-service服務的pom文件中引入feign的依賴:
<!--feign依賴-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
🦋1.2 添加注解
在order-service的啟動類添加注解開啟Feign的功能:
🦋1.3 編寫Feign的客戶端
在order-service中新建一個接口,內容如下:
package cn.itcast.order.client;import cn.itcast.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);
}
這個客戶端主要是基于SpringMVC的注解來聲明遠程調用的信息,比如:
- 服務名稱:userservice
- 請求方式:GET
- 請求路徑:/user/{id}
- 請求參數:Long id
- 返回值類型:User
這樣,Feign就可以幫助我們發送http請求,無需自己使用RestTemplate來發送了。
🦋1.4 測試
修改order-service中的OrderService類中的queryOrderById方法,使用Feign客戶端代替RestTemplate:
運行
🔎2.自定義配置
Feign可以支持很多的自定義配置,如下表所示:
類型 | 作用 | 說明 |
---|---|---|
feign.Logger.Level | 修改日志級別 | 包含四種不同的級別:NONE、BASIC、HEADERS、FULL |
feign.codec.Decoder | 響應結果的解析器 | http遠程調用的結果做解析,例如解析json字符串為java對象 |
feign.codec.Encoder | 請求參數編碼 | 將請求參數編碼,便于通過http請求發送 |
feign. Contract | 支持的注解格式 | 默認是SpringMVC的注解 |
feign. Retryer | 失敗重試機制 | 請求失敗的重試機制,默認是沒有,不過會使用Ribbon的重試 |
一般情況下,默認值就能滿足我們使用,如果要自定義時,只需要創建自定義的@Bean覆蓋默認Bean即可。
下面以日志為例來演示如何自定義配置。
🦋2.1 配置文件方式
基于配置文件修改feign的日志級別可以針對單個服務,可以在order-service中添加:
feign: client:config: userservice: # 針對某個微服務的配置loggerLevel: FULL # 日志級別
也可以針對所有服務:
feign: client:config: default: # 這里用default就是全局配置,如果是寫服務名稱,則是針對某個微服務的配置loggerLevel: FULL # 日志級別
如下圖所示:
而日志的級別分為四種:
- NONE:不記錄任何日志信息,這是默認值。
- BASIC:僅記錄請求的方法,URL以及響應狀態碼和執行時間
- HEADERS:在BASIC的基礎上,額外記錄了請求和響應的頭信息
- FULL:記錄所有請求和響應的明細,包括頭信息、請求體、元數據。
🦋2.2 Java代碼方式
也可以基于Java代碼來修改日志級別,先聲明一個類,然后聲明一個Logger.Level的對象:
public class DefaultFeignConfiguration {@Beanpublic Logger.Level feignLogLevel(){return Logger.Level.BASIC; // 日志級別為BASIC}
}
如果要全局生效,將其放到啟動類的@EnableFeignClients這個注解中:
@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration.class)
如果是局部生效,則把它放到對應的@FeignClient這個注解中:
@FeignClient(value = "userservice", configuration = DefaultFeignConfiguration .class)
優先級配置文件要高于代碼聲明式,如果想驗證新的需先注釋配置文件中的配置項
🔎3.Feign使用優化
Feign底層發起http請求,依賴于其它的框架。其底層客戶端實現包括:
-
URLConnection:默認實現,不支持連接池
-
Apache HttpClient :支持連接池
-
OKHttp:支持連接池
因此提高Feign的性能主要手段就是使用連接池代替默認的URLConnection。
這里我們用Apache的HttpClient來演示。
1)引入依賴
在order-service的pom文件中引入Apache的HttpClient依賴:
<!--httpClient的依賴 -->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId>
</dependency>
2)配置連接池
在order-service的application.yml中添加配置:
feign:client:config:default: # default全局的配置loggerLevel: BASIC # 日志級別,BASIC就是基本的請求和響應信息httpclient:enabled: true # 開啟feign對HttpClient的支持max-connections: 200 # 最大的連接數max-connections-per-route: 50 # 每個路徑的最大連接數
運行測試
🔎4.最佳實踐
🦋4.1 繼承方式
一樣的代碼可以通過繼承來共享:
1)定義一個API接口,利用定義方法,并基于SpringMVC注解做聲明。
2)Feign客戶端和Controller都集成改接口
優點:
- 簡單
- 實現了代碼共享
缺點:
-
服務提供方、服務消費方緊耦合
-
參數列表中的注解映射并不會繼承,因此Controller中必須再次聲明方法、參數列表、注解
🦋4.2 抽取方式
將Feign的Client抽取為獨立模塊,并且把接口有關的POJO、默認的Feign配置都放到這個模塊中,提供給所有消費者使用。
例如,將UserClient、User、Feign的默認配置都抽取到一個feign-api包中,所有微服務引用該依賴包,即可直接使用。
🦋4.3 實現基于抽取的最佳實踐
??4.3.1 抽取
首先創建一個module,命名為feign-api:
在feign-api中然后引入feign的starter依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>cloud-demo</artifactId><groupId>cn.itcast.demo</groupId><version>1.0</version></parent><modelVersion>4.0.0</modelVersion><artifactId>feign-api</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency></dependencies>
</project>
然后,order-service中編寫的UserClient、User、DefaultFeignConfiguration都復制到feign-api項目中
??4.3.2 在order-service中使用feign-api
首先,刪除order-service中的UserClient、User、DefaultFeignConfiguration等類或接口。
在order-service的pom文件中中引入feign-api的依賴:
<!--feign-api的依賴 -->
<dependency><groupId>cn.itcast.demo</groupId><artifactId>feign-api</artifactId><version>1.0</version>
</dependency>
修改order-service中的所有與上述三個組件有關的導包部分,改成導入feign-api中的包
- 刪除order-service中的User類
- 更新依賴:cn.itcast.order.pojo.Order
- 更新依賴:cn.itcast.order.client.UserClient
- 更新依賴:cn.itcast.order.service.OrderService
以下調整均在啟動類中增加
方式一:
指定Feign應該掃描的包:
@EnableFeignClients(basePackages = "cn.itcast.feign.clients")
方式二:
指定需要加載的Client接口(注意引包是:feign-api下的別引錯了):
@EnableFeignClients(clients = {UserClient.class})
??4.3.3 重啟測試
🚀感謝:給讀者的一封信
親愛的讀者,
我在這篇文章中投入了大量的心血和時間,希望為您提供有價值的內容。這篇文章包含了深入的研究和個人經驗,我相信這些信息對您非常有幫助。
如果您覺得這篇文章對您有所幫助,我誠懇地請求您考慮贊賞1元錢的支持。這個金額不會對您的財務狀況造成負擔,但它會對我繼續創作高質量的內容產生積極的影響。
我之所以寫這篇文章,是因為我熱愛分享有用的知識和見解。您的支持將幫助我繼續這個使命,也鼓勵我花更多的時間和精力創作更多有價值的內容。
如果您愿意支持我的創作,請掃描下面二維碼,您的支持將不勝感激。同時,如果您有任何反饋或建議,也歡迎與我分享。
再次感謝您的閱讀和支持!
最誠摯的問候, “愚公搬代碼”