數(shù)人云老王:今天主要分享三個議題垂蜗,首先是Google數(shù)據(jù)中心的簡單介紹——Google數(shù)據(jù)中心約有200萬臺X86PC服務(wù),沒有買任何大烘苹、小型機片部,完全使用廉價的PC服務(wù)器搭建,因規(guī)模龐大廊鸥,所以對網(wǎng)絡(luò)要求非常高辖所,交換機都是自行設(shè)計后定制的缘回。服務(wù)發(fā)現(xiàn)、負(fù)載均衡的問題揩环,對于Google的量級來說非常復(fù)雜幅虑,此次跟大家分享下Google內(nèi)部如何實現(xiàn)服務(wù)發(fā)現(xiàn)和負(fù)載均衡倒庵。
經(jīng)典的服務(wù)發(fā)現(xiàn)與負(fù)載均衡
靜態(tài)的服務(wù)發(fā)現(xiàn)方式其實很好理解,即基于IP地址和端口做服務(wù)發(fā)現(xiàn)郁妈,應(yīng)用綁定了服務(wù)器的IP地址和端口后绍申,當(dāng)有請求時极阅,應(yīng)用就可以接收。
經(jīng)典的負(fù)載均衡器也是綁定某個特定的IP地址和端口仆百,同時負(fù)載均衡器將需要做負(fù)載均衡的應(yīng)用實例預(yù)先配置好奔脐,當(dāng)負(fù)載均衡器收到請求后即可分發(fā)給后臺的應(yīng)用實例。
用IP+端口的方式做服務(wù)發(fā)現(xiàn)對人不友好峦朗,因為IP地址不好記憶甚垦,所以人們又發(fā)明了DNS作為非常經(jīng)典的服務(wù)發(fā)現(xiàn)方式。
DNS實現(xiàn)的是域名解析闭翩,比較常用的方式是A記錄向:DNS查詢某個域名的A紀(jì)錄會返回該域名對應(yīng)的一個或多個IP地址迄埃,圖上圖所示侄非,給定一個域名,通過查詢DNS服務(wù)器返回來這個域名所對應(yīng)的IP地址者疤。
另外一種DNS解析方式是SRV記錄叠赦,這是DNS里實現(xiàn)更高級服務(wù)發(fā)現(xiàn)的一種方式除秀,向DNS查詢某個域名的SRV記錄要返回該域名對應(yīng)的一個或多哥地址及端口,如上圖所示泳姐,向DNS查詢一個域名地址暂吉,DNS返回了該域名對應(yīng)的一系列地址和端口慕的。
DNS除了具有服務(wù)發(fā)現(xiàn)功能,也可以實現(xiàn)負(fù)載均衡,如上圖所示低散,DNS可以根據(jù)用戶請求,動態(tài)的返回某域名的A紀(jì)錄稽鞭,如引镊,DNS返回的A紀(jì)錄是目前最不繁忙的實例IP地址弟头,這樣DNS就可以實現(xiàn)負(fù)載均衡的功能。
靜態(tài)環(huán)境下的負(fù)載均衡是最常見的負(fù)載均衡器使用場景疹娶,如上圖所示伦连,用戶的請求發(fā)給負(fù)載均衡器惑淳,其根據(jù)一定的策略,如輪轉(zhuǎn)策略或暗轉(zhuǎn)一定的權(quán)重把收到的請求分發(fā)給后面具體的應(yīng)用實例移斩,應(yīng)用實例在處理完請求后把響應(yīng)返回給負(fù)載均衡器倚舀,之后負(fù)載均衡器再把請求響應(yīng)返回給最終用戶痕貌。
常見的負(fù)載均衡器支持四層和七層協(xié)議,具體來說就是TCP協(xié)議和HTTP協(xié)議超升。
四層負(fù)載均衡器室琢,按照TCP協(xié)議來說是實現(xiàn)了一種路由轉(zhuǎn)發(fā)——一個TCP請求數(shù)據(jù)包經(jīng)過四層負(fù)載均衡器時落追,負(fù)載均衡器只修改這個TCP請求數(shù)據(jù)包的目的地址然后轉(zhuǎn)給后面的應(yīng)用實例;當(dāng)負(fù)載均衡器收到應(yīng)用實例返回的TCP響應(yīng)數(shù)據(jù)包時巢钓,會修改這個TCP響應(yīng)數(shù)據(jù)包的目的地址然后返回給用戶。
七層負(fù)載均衡器和四層負(fù)載均衡器的工作原理不一樣硫朦,當(dāng)七層負(fù)載均衡器收到一個用戶的HTTP請求數(shù)據(jù)包會把該請求包拆掉咬展,然后封裝成一個新的HTTP請求數(shù)據(jù)包傳給后面的應(yīng)用實例瞒斩;當(dāng)負(fù)載均衡器收到應(yīng)用實例返回的HTTP響應(yīng)數(shù)據(jù)包時济瓢,會把HTTP響應(yīng)數(shù)據(jù)包拆掉然后重新封裝一個新的HTTP響應(yīng)數(shù)據(jù)包返回給用戶,所以四層和七層負(fù)載均衡器的工作原理不同蔑鹦,四層類似于路由轉(zhuǎn)發(fā)箕宙,七層則是完全重新封裝的包柬帕。
常見的服務(wù)發(fā)現(xiàn)方式有三種:
第一種是用IP地址+端口或域名+端口的方式做服務(wù)發(fā)現(xiàn),比如锅很,“website.com:8080”代表一個應(yīng)用凤跑,“website.com:8081”代表另一個應(yīng)用仔引,雖然這兩個應(yīng)用的域名相同。這種方式適用于四層和七層協(xié)議翘簇,即TCP及HTTP協(xié)議都可以用儿倒。
第二種是子域名的方式,僅適用于七層協(xié)議蹈垢,子域名的方式是指不同的應(yīng)用可能有共同的根源袖裕,但是有不同的子域名溉瓶,比如http://service1.zone1.website.com和http://service2.zone1.website.com堰酿,這兩個不同的域名(訪問端口都是80),有共同的根域名website.com坎藐,但子域名不同岩馍,因此七層協(xié)議如HTTP協(xié)議會通過不同的子域名解析到不同的應(yīng)用抖韩。
第三種是子路徑的方式,也僅適用于七層協(xié)議双谆,如http://zone1.website.com/service1和http://zone1.website.com/service2顽馋,兩個路徑的域名完全一樣幌羞,但子路徑不同新翎,可以用于區(qū)分不同的應(yīng)用服務(wù)。
這三種服務(wù)發(fā)現(xiàn)方式其實總結(jié)下來只有IP地址或者域名+端口同時適用于四層愁拭、七層亏吝,其他如子域名、子路徑的方式只適用于七層服務(wù)發(fā)現(xiàn)许赃。
動態(tài)環(huán)境
上述都是非常經(jīng)典的負(fù)載均衡馆类、服務(wù)發(fā)現(xiàn)的基本概念和做法乾巧,但當(dāng)數(shù)據(jù)中心規(guī)模達(dá)到一定程度時應(yīng)用和服務(wù)器之間更確切的說應(yīng)用和具體IP地址+端口之間就不再是靜態(tài)的綁定關(guān)系。
如Google的數(shù)據(jù)中心大約有200萬臺服務(wù)器咳胃,若Google的應(yīng)用和服務(wù)器之間是一一對應(yīng)的靜態(tài)綁定關(guān)系:即某個應(yīng)用必須要綁在某一個服務(wù)武器上旷太,或者綁定某個服務(wù)器的IP地址+端口上供璧,那么對Google來說,每時每刻大概會有幾百萬到上千萬個應(yīng)用運行在200萬臺服務(wù)器中金句,靜態(tài)管理應(yīng)用和服務(wù)器非常復(fù)雜违寞,因此對于Google這樣龐大規(guī)模的數(shù)據(jù)中心來說偶房,必須用動態(tài)管理,即要求應(yīng)用不能以靜態(tài)綁定在服務(wù)器的IP地址+端口上棕洋,它可以在不同的服務(wù)器之間動態(tài)遷移來實現(xiàn)故障自愈挡闰,應(yīng)用運行在某一個服務(wù)器上,這個服務(wù)器宕機或有問題掰盘,會被自動遷移到別的服務(wù)器上回復(fù)運行摄悯,動態(tài)的應(yīng)用調(diào)度管理方式可以使應(yīng)用的管理即服務(wù)器的管理進(jìn)行解耦——應(yīng)用和服務(wù)器之間不再是靜態(tài)的綁定關(guān)系。
動態(tài)環(huán)境下如何做負(fù)載均衡和服務(wù)發(fā)現(xiàn)愧捕?首先要明確問題奢驯,動態(tài)環(huán)境最根本的一點是要把服務(wù)發(fā)現(xiàn)實現(xiàn),客戶端要找到服務(wù)的后臺瘪阁,它從哪里找撒遣?這就是服務(wù)發(fā)現(xiàn),在動態(tài)的環(huán)境下其實并不復(fù)雜管跺,每個服務(wù)的后臺實例綁定的IP地址和端口注冊側(cè)到一個服務(wù)注冊中心义黎,注冊的方式可以是被動注冊也可以是主動注冊,被動注冊是指負(fù)責(zé)應(yīng)用調(diào)度的調(diào)度器來完成應(yīng)用實例的IP地址+端口注冊豁跑;主動注冊是指每一個服務(wù)的實例要主動地上報自己目前所綁定的IP地址+端口廉涕。
有了動態(tài)服務(wù)注冊機制后,動態(tài)環(huán)境下的負(fù)載均衡也就好實現(xiàn)了艇拍,在動態(tài)環(huán)境下火的,當(dāng)負(fù)載均衡器收到一個請求后,會去服務(wù)注冊中心進(jìn)行查詢響應(yīng)的應(yīng)用實例地址淑倾,然后把請求路由到該應(yīng)用的后臺實例上。
實例:數(shù)人云Swan
Google內(nèi)部的服務(wù)發(fā)現(xiàn)和負(fù)載均衡外面看不到征椒,數(shù)人云借鑒Google的理念實現(xiàn)了Swan(Github地址:https://github.com/Dataman-Cloud/swan )娇哆,Swan基于Mesos來做容器化應(yīng)用的動態(tài)調(diào)度,同時Swan實現(xiàn)了DNS和Proxy支持服務(wù)發(fā)現(xiàn)和負(fù)載均衡勃救,跟Google的方式幾乎一模一樣碍讨,因此后面用Swan作例子給大家分享下Google怎么做服務(wù)發(fā)現(xiàn)和負(fù)載均衡。
首先蒙秒,如何給應(yīng)用命名勃黍,在動態(tài)的應(yīng)用調(diào)度和運行的環(huán)境下非常重要,因為經(jīng)典的應(yīng)用發(fā)現(xiàn)偶讀是按照IP和端口晕讲,沒有對應(yīng)用有統(tǒng)一的命名覆获,但Google對于每個應(yīng)用、實例都會有相應(yīng)的命名瓢省,要明確幾個概念:
- 一個實例弄息,是應(yīng)用的某個Task,運行在一個容器里勤婚,應(yīng)用會包含多個Task摹量,都是運行同樣的二進(jìn)制程序;
- 一個應(yīng)用馒胆,是一組運行同樣二進(jìn)制程序的實例集合缨称,每個實例是這個應(yīng)用的某個Task;
- 一組服務(wù)可以是一組應(yīng)用程序祝迂;
- 一個服務(wù)會由一個用戶在某個集群上發(fā)起運行睦尽。
Swan給每個實例用五個標(biāo)簽去命名,task-app-service-user-cluster 液兽,Task是從0開始的連續(xù)整數(shù)骂删,用于標(biāo)識不同實例掌动;相應(yīng)地Swan給每個應(yīng)用四個標(biāo)簽來命名,app-service-user-cluster宁玫;進(jìn)而粗恢,Swan給每個服務(wù)用是三個標(biāo)簽來命名,service-user-cluster欧瘪。
Swan實現(xiàn)了DNS用于服務(wù)發(fā)現(xiàn)眷射,即Swan DNS把Swan調(diào)度的每一個實例所綁定的IP地址+端口的信息都記錄下來,或是A記錄或是SRV記錄佛掖。
對于每個應(yīng)用妖碉,Swan的DNS也生成一個相應(yīng)的域名用于四層服務(wù)發(fā)現(xiàn),即app.service.user.cluster.swan.com 芥被。另外七層的應(yīng)用SwanProx會解析應(yīng)用的另外一個域名http://app.service.user.cluster.gateway.swan.com 欧宜,用于七層應(yīng)用的服務(wù)發(fā)現(xiàn)和負(fù)載均衡。
上圖是Swan架構(gòu)的示意圖拴魄,簡單解釋了Swan冗茸、DNS、Proxy之間的關(guān)系:如何通過Swan對應(yīng)用動態(tài)調(diào)度后實現(xiàn)服務(wù)發(fā)現(xiàn)和負(fù)載均衡匹中,舉例說明:首先夏漱,Swan發(fā)布一個應(yīng)用app-app-service-user-cluster ,包含三個實例分別是:0-app-service-user-cluster顶捷,1-app-service-user-cluster挂绰,2-app-service-user-cluster;當(dāng)Swan把三個實例都運行起來后服赎,會將三個實例目前運行時所綁定的IP+端口信息提交給Swan DNS葵蒂。
比如可以訪問Swan DNS去解析app.service.user.cluster.swan.com這個域名,會解析出來三個容器的實例专肪;當(dāng)用戶的請求訪問app.service.user.cluster.gateway.swan.com刹勃,該請求會送達(dá)到Swan Proxy上,因為Swan Proxy地址是gateway.swan.com 嚎尤,Swan Proxy采用子域名的方式解析app.service.user.cluster荔仁,在解析此地址時會查Swan DNS,查此應(yīng)用所對應(yīng)的實例芽死,每個實例分別在哪個IP+端口上乏梁,Swan Proxy查詢了Swan DNS后,發(fā)現(xiàn)它后面有三個實例,分別在不同的IP和端口上,當(dāng)Swan Proxy收到對這個應(yīng)用請求時回分別往后面三個實例上進(jìn)行分發(fā)棉浸。
上圖詳細(xì)地解析了Swan DNS如何做服務(wù)發(fā)現(xiàn),展示了Swan DNS里面的A紀(jì)錄落萎,圖里對應(yīng)的A紀(jì)錄是nginx-demo.default.xcm.beijing.swan.com應(yīng)用亥啦,應(yīng)用名稱為nginx-demo,屬于default服務(wù)练链,用戶為是:xcm翔脱,default 服務(wù)目前運行在beijing數(shù)據(jù)中心中,swan.com作為一個后綴去表示是Swan的內(nèi)網(wǎng)域名媒鼓,A紀(jì)錄展現(xiàn)出應(yīng)用有6個實例届吁,都在192.168.1.196的IP地址上。
上圖是Swan DNS的SRV記錄绿鸣,SRV記錄和A記錄不同之處是A記錄只返回域名的IP地址疚沐,SRV記錄要返回域名的IP地址+端口。上圖所示的SRV查詢結(jié)果包含了6個不同的應(yīng)用實例潮模,分別在不同的端口上亮蛔,6個不同的實例又在同一個IP地址上:192.168.1.196,但它們綁定的端口不一樣:31000擎厢、31001尔邓、301002、301003锉矢、301004、301005齿尽、31006沽损。
Swan實現(xiàn)了Proxy用于負(fù)載均衡。
七層負(fù)載均衡:通過Swan Proxy支持子域名方式實現(xiàn)前面提到循头,用戶的HTTP請求發(fā)往app.service.user.cluster.gateway.swan.com這個域名地址時绵估,先是.gateway.swan.com解析到Swan Proxy的IP地址上,然后因為Swan Proxy針對HTTP協(xié)議做解析的時候它會解析HTTP協(xié)議里面的域名卡骂,這個域名的子域名就是app.service.user.cluster国裳,也就是這個域名里面的前綴。按照這個前綴全跨,Swan Proxy可以區(qū)分出該HTTP請求是要訪問哪個具體的應(yīng)用缝左。Swan Proxy在做HTTP這個服務(wù)發(fā)現(xiàn)負(fù)載均衡的時候會支持會話保持,也會支持HTTPS浓若。
但是Swan Proxy不支持HTTP子路徑方式渺杉,因為子路徑的方式本質(zhì)上講不是一種負(fù)載均衡的方式,子路徑其實和應(yīng)用所提供的不同服務(wù)相關(guān)的挪钓,所以具體的子路徑服務(wù)的注冊方式需要用額外的是越,比如微服務(wù)自身的服務(wù)發(fā)現(xiàn)支持,比如SpringCloud里面的Eurake或者阿里的Dubbo這些服務(wù)注冊中心來做子路徑方式的服務(wù)注冊碌上。
四層負(fù)載均衡:因為四層協(xié)議倚评,比如TCP協(xié)議浦徊,的特殊性,Swan Proxy支持的TCP協(xié)議只能是端口方式天梧,根據(jù)一個Swan Proxy的IP或者Swan Proxy的域名盔性,加上不同的端口來區(qū)分不同的應(yīng)用。Swan Proxy在對TCP進(jìn)行負(fù)載均衡的時候也會支持會話保持腿倚。
最后匯總下Swan的服務(wù)發(fā)現(xiàn)纯出、負(fù)載均衡方式。結(jié)合容器目前的幾種網(wǎng)絡(luò)模式:Bridge方式敷燎、Host方式還有固定IP的方式暂筝,上圖給出Swan在不同容器的網(wǎng)絡(luò)模式下如何做服務(wù)發(fā)現(xiàn)、負(fù)載均衡硬贯。
王璞本次分享介紹了經(jīng)典的四層焕襟、七層負(fù)載均衡以及服務(wù)發(fā)現(xiàn)的三種方式,又以Google數(shù)據(jù)中心入手饭豹,講述了大體量動態(tài)環(huán)境的負(fù)載均衡及服務(wù)發(fā)現(xiàn)方式鸵赖,最后以數(shù)人云Swan為例,進(jìn)行了詳細(xì)講解拄衰,小數(shù)希望大家看后有所收獲它褪。