微服務架構如何實現客戶端負載均衡

?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)化這些成為架構師必備的知識體系祟辟。還能領取免費的學習資源医瘫,目前受益良多

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市旧困,隨后出現的幾起案子醇份,更是在濱河造成了極大的恐慌稼锅,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件僚纷,死亡現場離奇詭異矩距,居然都是意外死亡,警方通過查閱死者的電腦和手機畔濒,發(fā)現死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門剩晴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人侵状,你說我怎么就攤上這事赞弥。” “怎么了趣兄?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵绽左,是天一觀的道長。 經常有香客問我艇潭,道長拼窥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任蹋凝,我火速辦了婚禮鲁纠,結果婚禮上,老公的妹妹穿的比我還像新娘鳍寂。我一直安慰自己改含,他們只是感情好,可當我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布迄汛。 她就那樣靜靜地躺著捍壤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鞍爱。 梳的紋絲不亂的頭發(fā)上鹃觉,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天,我揣著相機與錄音睹逃,去河邊找鬼盗扇。 笑死,一個胖子當著我的面吹牛沉填,可吹牛的內容都是我干的粱玲。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼拜轨,長吁一口氣:“原來是場噩夢啊……” “哼抽减!你這毒婦竟也來了?” 一聲冷哼從身側響起橄碾,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤卵沉,失蹤者是張志新(化名)和其女友劉穎颠锉,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體史汗,經...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡琼掠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了停撞。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瓷蛙。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖戈毒,靈堂內的尸體忽然破棺而出艰猬,到底是詐尸還是另有隱情,我是刑警寧澤埋市,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布冠桃,位于F島的核電站,受9級特大地震影響道宅,放射性物質發(fā)生泄漏食听。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一污茵、第九天 我趴在偏房一處隱蔽的房頂上張望樱报。 院中可真熱鬧,春花似錦泞当、人聲如沸肃弟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至穷缤,卻和暖如春敌蜂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背津肛。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工章喉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人身坐。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓秸脱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親部蛇。 傳聞我的和親對象是個殘疾皇子摊唇,可洞房花燭夜當晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內容