首先說明一下,feign只是一個宣告式的Http客戶端,提供以宣告式的方式定義Http呼叫。本身並沒有實現負載均衡,負載均衡是ribbon實現的,feign只是使用而已。
我從不使用feign進行介面呼叫開始,到使用feign進行介面呼叫,來說明使用和不使用feign的區別以及如何實現負載均衡的。
不使用Feign的情況下,進行介面呼叫,一般都是使用Spring提供的RestTemplate。RestTempate提供了很多呼叫介面的方法,你可以簡單的把RestTemplate理解為是Spring提供的HttpClient。
如果要實現負載均衡,那麼只需要加一個LoadBalanced註解,就像下面這樣:
那它是怎麼實現負載均衡的呢?簡單梳理一下原始碼:
LoadBalancerAutoConfiguration中有下面這段程式碼,它會將所有有LoadBalanced註解的RestTemplate注入進來
然後透過下面的邏輯,將負載均衡邏輯給新增進去
RestTemplate會在執行之前,先執行攔截器,然後去執行最終的請求
而攔截器中有負載均衡邏輯
首先客戶端從服務列表中獲取到所有的服務列表資訊
使用RestTemplate有什麼問題呢?
和RestTemplate強依賴,不利於擴充套件或重構
和本地介面呼叫方式不統一
假設我要呼叫一個遠端介面,獲取使用者的資訊。那麼我們可以這麼寫:
1處,註解UserApiService為FeignClient,其中的name是需要呼叫的應用的AppName,即註冊到註冊中心上的名字
怎麼呼叫呢?
呼叫方式是不是和普通的介面一樣?呼叫端根本就不必關係UserApiService是一個本地實現,還是一個遠端呼叫。這就解決了上面提到的兩個問題。
首先說明一下,feign只是一個宣告式的Http客戶端,提供以宣告式的方式定義Http呼叫。本身並沒有實現負載均衡,負載均衡是ribbon實現的,feign只是使用而已。
我從不使用feign進行介面呼叫開始,到使用feign進行介面呼叫,來說明使用和不使用feign的區別以及如何實現負載均衡的。
不使用Feign的呼叫不使用Feign的情況下,進行介面呼叫,一般都是使用Spring提供的RestTemplate。RestTempate提供了很多呼叫介面的方法,你可以簡單的把RestTemplate理解為是Spring提供的HttpClient。
如果要實現負載均衡,那麼只需要加一個LoadBalanced註解,就像下面這樣:
那它是怎麼實現負載均衡的呢?簡單梳理一下原始碼:
LoadBalancerAutoConfiguration中有下面這段程式碼,它會將所有有LoadBalanced註解的RestTemplate注入進來
然後透過下面的邏輯,將負載均衡邏輯給新增進去
RestTemplate會在執行之前,先執行攔截器,然後去執行最終的請求
而攔截器中有負載均衡邏輯
首先客戶端從服務列表中獲取到所有的服務列表資訊
客戶端按照負載均衡演算法邏輯,選擇一個服務進行呼叫具體程式碼流程比較複雜,這裡不具體說明,後續可能會專門寫幾篇關於SpringCloud原始碼分析的文章問題使用RestTemplate有什麼問題呢?
和RestTemplate強依賴,不利於擴充套件或重構
和本地介面呼叫方式不統一
我們來看看使用Feign後會變成什麼情況。使用Feign假設我要呼叫一個遠端介面,獲取使用者的資訊。那麼我們可以這麼寫:
1處,註解UserApiService為FeignClient,其中的name是需要呼叫的應用的AppName,即註冊到註冊中心上的名字
2處,宣告呼叫的介面的地址和Method,這裡是/api/getuserinfo,GET請求。1、2結合,即該介面訪問的地址是GET http://USER/api/getuserinfo3處,請求的引數。完整的請求是GET http://USER/api/getuserinfo?userName=ivan&password=123456怎麼呼叫呢?
呼叫方式是不是和普通的介面一樣?呼叫端根本就不必關係UserApiService是一個本地實現,還是一個遠端呼叫。這就解決了上面提到的兩個問題。