?Spring Cloud Ribbon 是一一基于HTTP 和TCP 的客戶端負載均衡工具而线,它基于NetflixRibbon實現翩剪。通過Spring Cloud 的封裝刹淌,可以讓我們輕松地將面向服務的REST 模板請求自動轉換成客戶端負載均衡的服務調用。Spring Cloud Ribbon 雖然只是一個工具類框架芹橡,它不像服務注冊中心毒坛、配置中心、API 網關那樣需要獨立部署林说,但是它兒乎存在于每一個SpringCloud 構建的微服務和基礎設施中粘驰。因為微服務間的調用,API 網關的請求轉發(fā)等內容述么,實際上都是通過Ribbon 來實現的,包括后續(xù)我們將要介紹的Feign,它也是基于Ribbon實現的工具愕掏。所以度秘,對Spring Cloud Ribbon 的理解和使用,對于我們使用Spring Cloud 來構建微服務非常重要饵撑。
在這里剑梳,我們將介紹如何使用Ribbon 來實現客戶端的負載均衡,并且通過源碼分析來了解Ribbon 實現客戶端負載均衡的基本原理滑潘。
客戶端負載均衡
負載均衡在系統(tǒng)架構中是一個非常重要垢乙,并且是不得不去實施的內容。因為負載均衡是對系統(tǒng)的高可用语卤、網絡壓力的緩解和處理能力擴容的重要手段之一追逮。我們通常所說的負載均衡都指的是服務端負載均衡,其中分為硬件負載均衡和軟件負載均衡粹舵。硬件負載均衡主要通過在服務器節(jié)點之間安裝專門用于負載均衡的設備钮孵,比如F5 等; 而軟件負載均衡則是通過在服務器上安裝一些具有均衡負載功能或模塊的軟件來完成請求分發(fā)工作,比如Nginx 等眼滤。不論采用硬件負載均衡還是軟件負載均衡巴席,只要是服務端負載均衡都能以架構方式構建起來:
? 硬件負載均衡的設備或是軟件負載均衡的軟件模塊都會維護一個下掛可用的服務端清單,通過心跳檢測來剔除故障的服務端節(jié)點以保證清單中都是可以正常訪問的服務端節(jié)點诅需。當客戶端發(fā)送請求到負載均衡設備的時候漾唉,該設備按某種算法(比如線性輪詢、按權重負載堰塌、按流量負載等)?從維護的可用服務端清單中取出一臺服務端的地址赵刑,然后進行轉發(fā)。
而客戶端負載均衡和服務端負我均衡最大的不同點在于上面所提到的服務清單所存儲的位置蔫仙。在客戶端負載均衡中料睛,所有客戶端節(jié)點都維護著自己要訪問的服務端清單,而這些服務端的清單來自于服務注冊中心,比如Eureka 服務端恤煞。同服務端負載均衡的架構類似屎勘,在客戶端負載均衡中也需要心跳去維護服務端清單的健康性,只是這個步驟需要與服務注冊中心配合完成居扒。在Spring Cloud 實現的服務治理框架中概漱,默認會創(chuàng)建針對各個服務治理框架的Ribbon 自動化整合配置,比如Eureka 中的org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration喜喂,Consul中的org.springframework.cloud.consul.discovery.RibbonConsulAuto-?Configurationo 在實際使用的時候瓤摧,我們可以通過查看這兩個類的實現,以找到它們的配置詳情來幫助我們更好地使用它玉吁。
通過SpringCloudRibbon 的封裝照弥,我們在微服務架構中使用客戶端負載均衡調用非常簡單,只需要如下兩步:
1.服務提供者只需要啟動多個服務實例并注冊到一個注冊中心或是多個相關聯(lián)的服務注冊中心进副。
2. 服務消費者直接通過調用被@LoadBalanced?注解修飾過的RestTemplate來實現面向服務的接口調用这揣。
??這樣,我們就可以將服務提供者的高可用以及服務消費者的負載均衡調用一起實現了影斑。 ?其中给赞,我們使用了個非常有用的對象RestTemplate.該對象會使用Ribbon?的自動化配置,同時通過配置@LoadBalanced?還能夠開啟客戶端負載均衡矫户。之前我們演示了通過RestTemplate實現了最簡單的服務訪問片迅,下面我們將詳細介紹RestTemplate?針對幾種不同請求類型和參數類型的服務調用實現。
??GET?請求
??在RestTemplate?中皆辽,對GET?請求可以通過如下兩個方法進行調用實現柑蛇。??第一種:?getForEntity?函數。該方法返回的是ResponseEntity,該對象是Spring對HTTP?請求響應的封裝膳汪,其中主要存儲了HTTP?的幾個重要元素唯蝶,比如HTTP?請求狀態(tài)馬的枚舉對象HttpStatus?(也就是我們常說的404、500?這些錯誤碼)遗嗽、在它的父類ittpEntity中還存儲著HTTP請求的頭信息對象HttpHeaders?以及泛型類型的請求體時象粘我。比如下面的例子,就是訪問USER-SERVER服務的/user?請求痹换,同時最后一個參數idi?會替換url?中的(1}占位符征字,而返回的ResponseEntity?對象中的body?內容類型:根據第二個參數轉換為String類型。
? ? RestTemplate?restTemplate?二newRestTemplate?()?;?
? ?ResponseEntityStri?xesponseEntity?一restTemplate.getFor?("http:?//USER-RVICE/user?name={1}",string.class,"didi")?;??
String?body=?responseEntity.getBody?()?;??
若我們希望返回的body是一個User對象類型娇豫,也可以這樣實現:?
? ?Restremplate?restTemplate=?new?Restremplate()?;??
? ResponseEntity?responseEntity?-restremplate.get?"http:?/USER-??vICE/user?name={1}"匙姜,User.class,"didi")?;
? user?body=?responseEntity.getBody?()?;?
?上面的例子是比較常用的方法
POST 請求
在RestTemplate 中,
對POST 請求時可以通過如下三個方法進行調用實現冯痢。
第一種: postEorEntity 函數氮昧。該方法同GET 請求中的getrorEntity 類似框杜,會
在調用后返回ResponseEntity對象,其中T 為請求響應的body 類型袖肥。
比如下面這
個例子咪辱,使用postForEntity 提交POST請求到USER-SERVICE 服務的/user 接口,
提交的body 內容為user對象椎组,請求響應返回的body 類型為String油狂。
RestTemplate restTemplate= new RestTemplate () ;
User user = new User ("didi",30) ;
ResponseEntity responseEntity=
restTemplate.postForEntity ("http: //USER-SERVICE/user",user,String.class) ;
String body= responseEntity.getBody () ;
postForEntity 函數也實現了三種不同的重載方法。
PUT?請求
GResTemplate中寸癌,對PUT請求可以通過pot?方法進行調用實現专筷,比如, ? ?
?? RestTemplaterestTemplate=new?RestTemplate();
? Long?id?=?100011;
? User?user=new?User("didi",40);
? restemplate.put(http://USER-SERVICE/user/{1} ”蒸苇,user,id ;
put?函數也實現了三種不同的重載方法:
1.put?(string?url,Object?request,0bject...urlVariables)
2.put?(Stringurl,Object?request,Map?urlVariables)
3.put?(URI?url,object?request?)
put函數為void類型磷蛹,所以沒有返回內容,也就沒有其他函數定義的responserype參數溪烤,除此之外的其他傳入參數定義與用法與postforobject基本一致弦聂。
DELETE?請求
在RestTemplate?中,對DELETE?請求可以通過delete?方法進行調用實現氛什,比如:
RestTemplate?restTemplate?=?new?RestTemplate?()?;
Long?id?=?10001L;restTemplate.delete?("http:?//USER-SERVICE/user/?(1}",id)?;
delete?函數也實現了三種不同的重載方法:
1.delete?(String?url,0bject...urlVariables)
2.delete?(String?url,Map?urlVariables)
3.delete?(URi url)由于我們在進行REST請求時匪凉,通常都將DELETE?請求的唯一標識拼接在url?中枪眉,所DELETE?請求也不需要equest?的body信息,就如上面的三個函數實現一樣再层,非常簡單贸铜。1指定DELETE?請求的位置,urlVariables?綁定url?中的參數即可聂受。
想學習更多更詳細的知識的蒿秦,在此我向大家推薦一個交流學習群:744642380 里面會分享一些資深架構師錄制的視頻錄像:有Spring,MyBatis蛋济,Netty源碼分析棍鳖,高并發(fā)、高性能碗旅、分布式渡处、微服務架構的原理,JVM性能優(yōu)化這些成為架構師必備的知識體系祟辟。還能領取免費的學習資源医瘫,目前受益良多