Spring Cloud OpenFeign 的五個優化小技巧!
作者 | 磊哥
來源 | Java中文社群(ID:javacn666)
轉載請聯絡授權(微信ID:GG_Stone)
OpenFeign 是 Spring 官方推出的一種宣告式服務呼叫和負載均衡元件。它的出現就是為了替代已經進入停更維護狀態的 Feign(Netflix Feign),同時它也是 Spring 官方的頂級開源專案。我們在日常的開發中使用它的頻率也很高,而 OpenFeign 有一些實用的小技巧,配置之後可以讓 OpenFeign 更好的執行,所以本文我們就來盤點一下(也歡迎各位老鐵評論區留言補充)。
一、超時優化
OpenFeign 底層內建了 Ribbon 框架,並且使用了 Ribbon 的請求連線超時時間和請求處理超時時間作為其超時時間,而 Ribbon 預設的請求連線超時時間和請求處理超時時間都是 1s,如下原始碼所示:
所有當我們使用 OpenFeign 呼叫了服務介面超過 1s,就會出現以下錯誤:
因為 1s 確實太短了,因此我們需要手動設定 OpenFeign 的超時時間以保證它能正確的處理業務。OpenFeign 的超時時間有以下兩種更改方法:
- 通過修改 Ribbon 的超時時間,被動的修改 OpenFeign 的超時時間。
- 直接修改 OpenFeign 的超時時間(推薦使用)。
1、設定Ribbon超時時間
在專案配置檔案 application.yml 中新增以下配置:
ribbon: ReadTimeout: 5000 # 請求連線的超時時間 ConnectionTimeout: 10000 # 請求處理的超時時間
2、設定OpenFeign超時時間
在專案配置檔案 application.yml 中新增以下配置:
feign: client: config: default: # 設定的全域性超時時間 connectTimeout: 2000 # 請求連線的超時時間 readTimeout: 5000 # 請求處理的超時時間
推薦使用此方式來設定 OpenFeign 的超時時間,因為這樣的(配置)語義更明確。
二、請求連線優化
OpenFeign 底層通訊元件預設使用 JDK 自帶的 URLConnection 物件進行 HTTP 請求的,因為沒有使用連線池,所以效能不是很好。我們可以將 OpenFeign 的通訊元件,手動替換成像 Apache HttpClient 或 OKHttp 這樣的專用通訊元件,這些的專用通訊元件自帶連線池可以更好地對 HTTP 連線物件進行重用與管理,同時也能大大的提升 HTTP 請求的效率。接下來我以 Apache HttpClient 為例,演示一下專用通訊元件的使用。
1、引入Apache HttpClient依賴
在專案的依賴管理檔案 pom.xml 中新增以下配置:
<!-- 新增 openfeign 框架依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- 新增 httpclient 框架依賴 --> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency>
2、開啟Apache HttpClient使用
啟動 Apache HttpClient 元件,在專案配置檔案 application.yml 中新增以下配置,:
feign: client: httpclient: # 開啟 HttpClient enabled: true
驗證 Apache HttpClient 配置是否生效,可以在 feign.SynchronousMethodHandler#executeAndDecode 方法上打斷點就可以看到了,如下圖所示:
三、資料壓縮
OpenFeign 預設不會開啟資料壓縮功能,但我們可以手動的開啟它的 Gzip 壓縮功能,這樣可以極大的提高寬頻利用率和加速資料的傳輸速度,在專案配置檔案 application.yml 中新增以下配置:
feign: compression: request: enabled: true # 開啟請求資料的壓縮功能 mime-types: text/xml,application/xml, application/json # 壓縮型別 min-request-size: 1024 # 最小壓縮值標準,當資料大於 1024 才會進行壓縮 response: enabled: true # 開啟響應資料壓縮功能
PS:如果服務消費端的 CPU 資源比較緊張的話,建議不要開啟資料的壓縮功能,因為資料壓縮和解壓都需要消耗 CPU 的資源,這樣反而會給 CPU 增加了額外的負擔,也會導致系統性能降低。
四、負載均衡優化
OpenFeign 底層使用的是 Ribbon 做負載均衡的,檢視原始碼我們可以看到它預設的負載均衡策略是輪詢策略,如下圖所示:
然而除了輪詢策略之外,我們還有其他 6 種內建的負載均衡策略可以選擇,這些負載均衡策略如下:
- 權重策略: WeightedResponseTimeRule,根據每個服務提供者的響應時間分配一個權重,響應時間越長,權重越小,被選中的可能性也就越低。它的實現原理是,剛開始使用輪詢策略並開啟一個計時器,每一段時間收集一次所有服務提供者的平均響應時間,然後再給每個服務提供者附上一個權重,權重越高被選中的概率也越大。
- 最小連線數策略: BestAvailableRule,也叫最小併發數策略,它是遍歷服務提供者列表,選取連線數最小的⼀個服務例項。如果有相同的最小連線數,那麼會呼叫輪詢策略進行選取。
- 區域敏感策略: ZoneAvoidanceRule,根據服務所在區域(zone)的效能和服務的可用性來選擇服務例項,在沒有區域的環境下,該策略和輪詢策略類似。
- 可用敏感性策略: AvailabilityFilteringRule,先過濾掉非健康的服務例項,然後再選擇連線數較小的服務例項。
- 隨機策略: RandomRule,從服務提供者的列表中隨機選擇一個服務例項。
- 重試策略: RetryRule,按照輪詢策略來獲取服務,如果獲取的服務例項為 null 或已經失效,則在指定的時間之內不斷地進行重試來獲取服務,如果超過指定時間依然沒獲取到服務例項則返回 null。
出於效能方面的考慮,我們可以選擇用權重策略或區域敏感策略來替代輪詢策略,因為這樣的執行效率最高。
五、日誌級別優化
OpenFeign 提供了日誌增強功能,它的日誌級別有以下幾個:
- NONE: 預設的,不顯示任何日誌。
- BASIC: 僅記錄請求方法、URL、響應狀態碼及執行時間。
- HEADERS: 除了 BASIC 中定義的資訊之外,還有請求和響應的頭資訊。
- FULL: 除了 HEADERS 中定義的資訊之外,還有請求和響應的正文及元資料。
我們可以通過配置檔案來設定日誌級別,配置資訊如下:
logging: level: cn.myjszl.service: debug
其中 cn.myjszl.service 為 OpenFeign 介面所在的包名。雖然 OpenFeign 預設是不輸出任何日誌,但在開發階段可能會被修改,因此在生產環境中,我們應仔細檢查並設定合理的日誌級別,以提高 OpenFeign 的執行效率。
總結
OpenFeign 是 Spring 官方推出的一種宣告式服務呼叫和負載均衡元件,在生產環境中我們可以通過以下配置來優化 OpenFeign 的執行:
- 修改 OpenFeign 的超時時間,讓 OpenFeign 能夠正確的處理業務。
- 通過配置專用的通訊元件 Apache HttpClient 或 OKHttp,讓 OpenFeign 可以更好地對 HTTP 連線物件進行重用和管理,以提高其效能。
- 開啟資料壓縮功能,可以提高寬頻利用率和加速資料傳輸速度。
- 使用合適的負載均衡策略來替換預設的輪詢負載均衡策略,已獲得更好的執行效率。
- 檢查生成環境中 OpenFeign 的日誌級別,選擇合適的日誌輸出級別,防止無效的日誌輸出。
- Web1.0到Web3.0,網際網路是如何演進的?
- DDD概念複雜難懂,實際落地如何設計程式碼實現模型?
- 學會一招!如何利用 pandas 批量合併 Excel?
- 超硬核!11個非常實用的 Python 和 Shell 拿來就用指令碼例項!
- 還在用requests寫爬蟲嗎?這個庫效率提高一倍!
- 分散式程式設計工具Akka Streams、Kafka Streams和Spark Streaming大PK
- 工具類如何獲取到 Spring 容器中的 Bean?
- code-review之前端程式碼優化彙總
- 七個讓我們成為更好 Vue 開發者的技巧
- 效率寶典:10個超實用的React Hooks庫
- 如何將HTML與Htmx一起使用並減少JavaScript程式碼量
- 一個依賴搞定Spring Boot 配置檔案脫敏
- 如何在 Python 中使用 DateTime
- 如何利用OpenTelemetry識別資料庫依賴關係?
- Node.js 子執行緒Crash 問題的排查
- 如何在Python中操作MySQL?
- 非同步非阻塞框架是如何實現的?
- 從 CPU 說起,深入理解 Java 記憶體模型!
- JavaScript逆向案例:破解登入密碼
- 如何從FreeBSD 12升級到FreeBSD13