(18)企業採購招標系統之Ribbon結合RestTemplate實現負載均衡
在上一篇教程中我們簡單地使用 Ribbon 進行了負載的一個呼叫,這意味著 Ribbon 是可以單獨使用的。推薦分散式架構原始碼。
在 Spring Cloud 中使用 Ribbon 會更簡單,因為 Spring Cloud 在 Ribbon 的基礎上進行了一層封裝,將很多配置都整合好了。本節將在 Spring Cloud 專案中使用 Ribbon。
使用 RestTemplate 與整合 Ribbon
Spring 提供了一種簡單便捷的模板類來進行 API 的呼叫,那就是 RestTemplate。
1.使用 RestTemplate
在前面介紹 Eureka 時,我們已經使用過 RestTemplate 了,本節會更加詳細地跟大家講解 RestTemplate 的具體使用方法。
首先我們來看看 GET 請求的使用方式:建立一個新的專案 spring-rest-template,配置好 RestTemplate:
新建一個 HouseController,並增加兩個介面,一個透過 @RequestParam 來傳遞引數,返回一個物件資訊;另一個透過 @PathVariable 來傳遞引數,返回一個字串。請儘量透過兩個介面組裝不同的形式,具體程式碼如下所示。
@GetMapping("/house/data") public HouseInfo getData(@RequestParam("name") String name) { return new HouseInfo(1L, "上海" "虹口" "東體小區"); } @GetMapping("/house/data/{name}") public String getData2(@PathVariable("name") String name) { return name; }
新建一個 HouseClientController 用於測試,使用 RestTemplate 來呼叫我們剛剛定義的兩個介面,程式碼如下所示。
獲取資料結果可透過 RestTemplate 的 getForObject 方法(如下程式碼所示)來實現,此方法有三個過載的實現:
url:請求的 API 地址,有兩種方式,其中一種是字串,另一種是 URI 形式。
responseType:返回值的型別。
uriVariables:PathVariable 引數,有兩種方式,其中一種是可變引數,另一種是 Map 形式。
除了 getForObject,我們還可以使用 getForEntity 來獲取資料,程式碼如下所示。
getForEntity 中可以獲取返回的狀態碼、請求頭等資訊,透過 getBody 獲取響應的內容。其餘的和 getForObject 一樣,也是有 3 個過載的實現。
接下來看看怎麼使用 POST 方式呼叫介面。在 HouseController 中增加一個 save 方法用來接收 HouseInfo 資料,程式碼如下所示。
接著寫呼叫程式碼,用 postForObject 來呼叫,程式碼如下所示。
postForObject 同樣有 3 個過載的實現。除了 postForObject 還可以使用 postForEntity 方法,用法都一樣,程式碼如下所示。
public <T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables); public <T> T postForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables); public <T> T postForObject(URI url, Object request, Class<T> responseType);
除了 get 和 post 對應的方法之外,RestTemplate 還提供了 put、delete 等操作方法,還有一個比較實用的就是 exchange 方法。exchange 可以執行 get、post、put、delete 這 4 種請求方式。更多地使用方式大家可以自行學習。
2.整合 Ribbon
在 Spring Cloud 專案中整合 Ribbon 只需要在 pom.xml 中加入下面的依賴即可,其實也可以不用配置,因為 Eureka 中已經引用了 Ribbon,程式碼如下所示。
RestTemplate 負載均衡示例
前面我們呼叫介面都是透過具體的介面地址來進行呼叫,RestTemplate 可以結合 Eureka 來動態發現服務並進行負載均衡的呼叫。
修改 RestTemplate 的配置,增加能夠讓 RestTemplate 具備負載均衡能力的註解 @LoadBalanced。程式碼如下所示。
修改介面呼叫的程式碼,將 IP+PORT 改成服務名稱,也就是註冊到 Eureka 中的名稱,程式碼如下所示。
介面呼叫的時候,框架內部會將服務名稱替換成具體的服務 IP 資訊,然後進行呼叫。 推薦分散式架構原始碼
@LoadBalanced 註解原理
相信大家一定有一個疑問:為什麼在 RestTemplate 上加了一個 @LoadBalanced 之後,RestTemplate 就能夠跟 Eureka 結合了,不但可以使用服務名稱去呼叫介面,還可以負載均衡?
應該歸功於 Spring Cloud 給我們做了大量的底層工作,因為它將這些都封裝好了,我們用起來才會那麼簡單。框架就是為了簡化程式碼,提高效率而產生的。
這裡主要的邏輯就是給 RestTemplate 增加攔截器,在請求之前對請求的地址進行替換,或者根據具體的負載策略選擇服務地址,然後再去呼叫,這就是 @LoadBalanced 的原理。
下面我們來實現一個簡單的攔截器,看看在呼叫介面之前會不會進入這個攔截器。我們不做任何操作,就輸出一句話,證明能進來就行了。具體程式碼如下所示。
攔截器設定好了之後,我們再定義一個註解,並複製 @LoadBalanced 的程式碼,改個名稱就可以了,程式碼如下所示。
然後定義一個配置類,給 RestTemplate 注入攔截器,程式碼如下所示。
維護一個 @MyLoadBalanced 的 RestTemplate 列表,在 SmartInitializingSingleton 中對 RestTemplate 進行攔截器設定。
然後改造我們之前的 RestTemplate 配置,將 @LoadBalanced 改成我們自定義的 @MyLoadBalanced,程式碼如下所示。
重啟服務,訪問服務中的介面就可以看到控制檯的輸出了,這證明在介面呼叫的時候會進入該攔截器,輸出如下:
進入自定義的請求攔截器中 ribbon-eureka-demo
透過這個小案例我們就能夠清楚地知道 @LoadBalanced 的工作原理。接下來我們來看看原始碼中是怎樣的一個邏輯。
首先看配置類,如何為 RestTemplate 設定攔截器,程式碼在 spring-cloud-commons.jar 中的 org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration 類裡面透過檢視 LoadBalancerAutoConfiguration 的原始碼,可以看到這裡也是維護了一個 @LoadBalanced 的 RestTemplate 列表,程式碼如下所示。
透過檢視攔截器的配置可以知道,攔截器用的是 LoadBalancerInterceptor,RestTemplate Customizer 用來新增攔截器,程式碼如下所示。
攔截器的程式碼在 org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor 中,程式碼如下所示。
主要的邏輯在 intercept 中,執行交給了 LoadBalancerClient 來處理,透過 LoadBalancer RequestFactory 來構建一個 LoadBalancerRequest 物件,程式碼如下所示。
createRequest 中透過 ServiceRequestWrapper 來執行替換 URI 的邏輯,ServiceRequest Wrapper 中將 URI 的獲取交給了 org.springframework.cloud.client.loadbalancer.LoadBalancer Client#reconstructURI 方法。
以上就是整個 RestTemplate 結合 @LoadBalanced 的執行流程,至於具體的實現大家可以自己去研究,這裡只介紹原理及整個流程。
Ribbon API 使用
當你有一些特殊的需求,想透過 Ribbon 獲取對應的服務資訊時,可以使用 Load-Balancer Client 來獲取,比如你想獲取一個 ribbon-eureka-demo 服務的服務地址,可以透過 LoadBalancerClient 的 choose 方法來選擇一個:
@Autowired private LoadBalancerClient loadBalancer; @GetMapping("/choose") public Object chooseUrl() { ServiceInstance instance = loadBalancer.choose("ribbon-eureka-demo"); return instance; }
訪問介面,可以看到返回的資訊如下:
Ribbon 飢餓載入
筆者從網上看到很多部落格中都提到過的一種情況:在進行服務呼叫的時候,如果網路情況不好,第一次呼叫會超時。有很多大神對此提出瞭解決方案,比如把超時時間改長一點、禁用超時等。
Spring Cloud 目前正在高速發展中,版本更新很快,我們能發現的問題基本上在版本更新的時候就修復了,或者提供最優的解決方案。
超時的問題也是一樣,Ribbon 的客戶端是在第一次請求的時候初始化的,如果超時時間比較短的話,初始化 Client 的時間再加上請求介面的時間,就會導致第一次請求超時。
本教程是基於 Finchley.SR2 撰寫的,這個版本已經提供了一種針對上述問題的解決方法,那就是 eager-load 方式。透過配置 eager-load 來提前初始化客戶端就可以解決這個問題。
ribbon.eager-load.enabled:開啟 Ribbon 的飢餓載入模式。
ribbon.eager-load.clients:指定需要飢餓載入的服務名,也就是你需要呼叫的服務,若有多個則用逗號隔開。
怎麼進行驗證呢?網路情況確實不太好模擬,不過透過除錯原始碼的方式即可驗證,在 org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration 中找到對應的程式碼,程式碼如下所示。
在 return 這行設定一個斷點,然後以除錯的模式啟動服務,如果能進入到這個斷點的程式碼這裡,就證明配置生效了 !
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70006413/viewspace-2920324/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- java Spring Cloud企業快速開發架構之Ribbon結合RestTemplate實現負載均衡JavaSpringCloud架構REST負載
- SpringCloud Fegin結合Ribbon實現負載均衡SpringGCCloud負載
- Ribbon實現負載均衡負載
- SpringCloud微服務中使用RestTemplate+Ribbon實現負載均衡(實現方法+實現原理+替換負載均衡策略)SpringGCCloud微服務REST負載
- 企業採購電子招投標系統
- 【SpringCloud】之Ribbon負載均衡SpringGCCloud負載
- 電子招標採購系統之電子招標採購系統功能清單
- SpringCloud大型企業分散式微服務+實現電子招標採購系統 電子招標採購平臺原始碼SpringGCCloud分散式微服務原始碼
- 企業電子招投標採購系統原始碼原始碼
- 電子招投標系統 —降低企業採購成本
- 負載均衡---ribbon負載
- 電子招標採購系統之Spring Cloud 電子招標採購系統功能清單SpringCloud
- 電子招投標採購系統原始碼之從採購系統原始碼
- spring cloud 企業電子招標採購系統原始碼SpringCloud原始碼
- java版本SpringCloud + spring boot 實現電子招標採購系統 電子招標採購平臺原始碼JavaGCCloudSpring Boot原始碼
- Spring Cloud Ribbon負載均衡SpringCloud負載
- java版本spring cloud 企業電子招標採購系統原始碼JavaSpringCloud原始碼
- Spring Cloud:使用Ribbon實現負載均衡詳解(上)SpringCloud負載
- Spring Cloud:使用Ribbon實現負載均衡詳解(下)SpringCloud負載
- SpringCloud微服務實戰——搭建企業級開發框架(十二):OpenFeign+Ribbon實現負載均衡SpringGCCloud微服務框架負載
- Spring Cloud之負載均衡元件Ribbon原理分析SpringCloud負載元件
- 企業電子招投標採購系統原始碼之首頁設計原始碼
- Ribbon負載均衡 (原始碼分析)負載原始碼
- Java 版 電子招標採購系統Java
- 數商雲採購管理系統助力企業打通企業採購環節,實現合規提效兩全其美
- SpringCloud系列之客戶端負載均衡Netflix RibbonSpringGCCloud客戶端負載
- 今日教學:RestTemplate 結合 Ribbon 使用REST
- 企業電子招標採購系統原始碼Spring Cloud + Spring Boot + MybatisPlus + Redis原始碼CloudSpring BootMyBatisRedis
- Spring Cloud入門教程-Ribbon實現客戶端負載均衡SpringCloud客戶端負載
- SpringCloud入門(四)Ribbon負載均衡SpringGCCloud負載
- SpringCloud 客戶端負載均衡:RibbonSpringGCCloud客戶端負載
- SpringCloud客戶端負載均衡——RibbonSpringGCCloud客戶端負載
- 客服端負載均衡:Spring Cloud Ribbon負載SpringCloud
- (4)什麼是Ribbon負載均衡負載
- 微服務負載均衡器 Ribbon微服務負載
- Spring cloud(3)-負載均衡(Feign,Ribbon)SpringCloud負載
- ③SpringCloud 實戰:使用 Ribbon 客戶端負載均衡SpringGCCloud客戶端負載
- 電子招標採購系統功能清單