摘要:前兩種的方式畢竟會多幾跳中轉(zhuǎn),但在路由的靈活性和通訊語義的提供更豐富的選擇,而且在大數(shù)據(jù)量的處理上,吞吐量和平均延時并不會比直連差很多??鐧C房的通信和本機房的通信有所不同本地機房的通信講究高吞吐量,類訪問會要求低延時。
(圖片源自網(wǎng)絡(luò))
2 架構(gòu)描述 簡單架構(gòu)從之前的描述,已經(jīng)可以看出我們會采用RPC over MQ的方式做底層實現(xiàn),類似方法調(diào)用的通信語義會在client和server兩端的庫中作封裝。
從后端實現(xiàn)來說,我們用三套后端來滿足不同的場景:
1、對大中型分布式系統(tǒng)環(huán)境,rabbitmq是非常非常好的支撐。本來以為需要自己做很多工作,但深入了解rabbitmq,尤其是其支持的amqp協(xié)議,發(fā)現(xiàn)其實前人在很多思路方面已經(jīng)栽好樹了,比如一致性hash和跨機房等功能,都有相應(yīng)的插件支撐。
所以,rabbitmq成為babel的第一選擇,可以實現(xiàn)我們規(guī)劃功能的全集,我們的SAAS平臺都是使用的rabbitmq。
2、對少量機器而言,redis提供了非常輕量級的隊列支持,可以提供有限但必要的功能。
redis沒有類似amqp這樣的協(xié)議,需要手動作些封裝。我們在單機環(huán)境使用redis,盡可能減少部署和運維的開銷。
3、對性能有苛刻要求的可以用zeromq后端去做tcp直連。前兩種mq的方式畢竟會多幾跳中轉(zhuǎn),但在路由的靈活性和通訊語義的提供更豐富的選擇,而且在大數(shù)據(jù)量的處理上,吞吐量和平均延時并不會比直連差很多。
但為了滿足特殊環(huán)境的需要,我們預(yù)留了zeromq的實現(xiàn)選擇,最近由于新的需求,正在準備完成這塊拼圖。zeromq的缺點在于需要中央配置系統(tǒng)來幫忙完成路由功能。
每種后臺實現(xiàn)對使用者透明,可以通過配置進行透明切換,但是有些高級通信語義redis和zeromq不支持。
如果對應(yīng)到web service 三要素:
UDDI:傳統(tǒng)的rpc或者SOA都是去注冊中心發(fā)現(xiàn)遠端對象,然后客戶端主動推送數(shù)據(jù)到服務(wù)端。mq的方式幫我們省卻了自注冊(訂閱實現(xiàn))和服務(wù)發(fā)現(xiàn)(mq自己路由)的問題。
WSDL:目前我們通過json的方式來描述rpc的service端,包括機房所在地,持久化,超時等等。
SOAP:目前使用json的方式,我們定義了一個統(tǒng)一的Event對象來封裝一些固定屬性,其他都在一個map中。由業(yè)務(wù)代碼自己去打包拆包。當(dāng)然這種方式在大團隊中不適合。
通訊語義封裝大量的工作可以利用mq來實現(xiàn),我們的工作主要體現(xiàn)在通訊語義的封裝。
? client端訪問模式語義
queue語義(消息有去無回):傳統(tǒng)的數(shù)據(jù)輸送。
簡單rpc(消息一去一回):傳統(tǒng)的rpc和soa都適用于此場景。
輪詢rpc(消息一去多回):一個request出去,多個response回來,適合于輪詢下游節(jié)點的場景。
分布式存儲rpc(一個request消息,只要有最小條件的response消息就返回):適合于分布式場景下的讀寫。例如三個拷貝,需要至少兩份讀成功或者至少兩份寫成功,等等。目前此方式我們還沒有用到。
? 消息分發(fā)語義(實際上這里的行為參考了storm的部分功能)
Shuffle:一個消息,會有多個接收者,這些接收者根據(jù)自己的資源情況去搶占同一來源的消息,達到load balance的目的。實際上我們通過shuffle來做集群功能,省掉了LB的引入。而且性能強的拉多點,性能弱的拉少點,變相的實現(xiàn)了根據(jù)消費者的性能來做分發(fā)。
Sharding:與shuffle類似,也是多個consumer來分享消息,不過根據(jù)消息的key,保證在拓撲環(huán)境不發(fā)生改變的情況下,同一個key始終指向同一個消費者,為后續(xù)分布式系統(tǒng)的搭建打下基礎(chǔ)
topic語義:所有消費者都會得到消息的一個拷貝。常見的mq語義
topic+shffule:一組消費者作為一個整體來訂閱topic,得到所有的消息,每個訂閱團體內(nèi)部通過shuffle的形式去分攤。這種非常適合用大數(shù)據(jù)環(huán)境下,有不同類型的數(shù)據(jù)消費者,每一個類型的消費者有各自的實例數(shù)。
topic+sharding:一組消費者作為一個整體來訂閱topic,得到所有的消息,每個訂閱團體內(nèi)部通過sharding的形式去分攤。類似于topic shuffle,只是換用了sharding這種更嚴格的語義。
? 數(shù)據(jù)的封裝語義。用于指定babel上承載數(shù)據(jù)的特征,例如:
batch operation:用于指定是否進行批處理傳遞。
Security:暫無使用。
Compressing:指定payload壓縮方法,目前只做了gzip。
機房:指定了機房所在地,框架會根據(jù)生產(chǎn)者和消費者的不同自動做跨機房的處理。
持久化:指定在無消費者的情況下,是否需要持久化存儲,以及最大大小。
超時:指定消息的最大有效時間,超過的消息將會被丟棄。
其他。
對于以上的通訊語義,首先需要去底層的mq基礎(chǔ)里面找到相對應(yīng)的設(shè)施來做封裝,比如對于queue語義作個簡單舉例:
而對于像rpc,輪詢,以及其他功能,則需要相應(yīng)的代碼來支撐,比如:
response的返回可以通過client監(jiān)聽queue來實現(xiàn)
response和request的串聯(lián)可以通過自定義的requestid來實現(xiàn)
輪詢可以通過client 端等待多個消息返回,可以用condition來做同步
……
這里有不少細節(jié),暫不在本文中進行展開了。
跨語言由于幾種mq都有python和java的客戶端,所以我們工作會輕松很多,只是同樣的邏輯需要寫兩份,好處還是很明顯的,使得我們的系統(tǒng)語言無關(guān),方便根據(jù)當(dāng)前人員的技能情況來分配開發(fā)任務(wù)。
不過這里不得不吐槽python的并發(fā),雖然有心理準備,沒想到是如此之差。當(dāng)使用多線程的時候,性能下降的厲害,比java要差兩個數(shù)量級,所以我們python版做了同步(多線程),異步(協(xié)程)兩個版本。異步版本的性能尚可接受;我們已經(jīng)準備在build自己的異步python框架,來覆蓋我們的應(yīng)用程序。
Babel的一大特色是跨機房通信,來幫助我們解決不同數(shù)據(jù)中心的通信問題,使得業(yè)務(wù)開發(fā)人員只用關(guān)心其所負責(zé)的業(yè)務(wù)即可??鐧C房的通信和本機房的通信有所不同:
本地機房的通信講究高吞吐量,rpc類訪問會要求低延時。
跨機房通信必須應(yīng)對復(fù)雜的網(wǎng)絡(luò)情況,要求數(shù)據(jù)不丟,rpc類通信可以接受相對較高的延時。
實現(xiàn)上,我們利用了federation插件,當(dāng)rpc框架發(fā)現(xiàn)存在跨機房訪問時,會自動啟用相應(yīng)的路由,下圖是同事畫的兩種情況下的路由,綠線是本地調(diào)用,紅線是跨機房調(diào)用。
對于業(yè)務(wù)應(yīng)用而言,使用上是基本透明的,借助于mq的中轉(zhuǎn),在多機房環(huán)境下它也可以玩轉(zhuǎn)除數(shù)據(jù)推送外的RPC類訪問語義。
3 實戰(zhàn)舉例 實例1 分布式數(shù)據(jù)計算平臺
首先是我們的私有化大數(shù)據(jù)平臺warden。warden集數(shù)據(jù)采集、轉(zhuǎn)換、分發(fā)、實時分析和展示等功能于一體,希望從客戶的原始網(wǎng)絡(luò)流量中找出異常點和風(fēng)險事件。
此圖是一個warden分布式版本的草圖:
采集的數(shù)據(jù)通過topic sharding類分配給不同類型的消費者,比如ES writer,Mysql writer,實時分析引擎;每種消費者可以有不同的實例數(shù)。
實時計算引擎通過sharding來分攤流量,達到scale out的效果。
rule引擎需要數(shù)據(jù)的時候同樣通過簡單的sharding的rpc就可以獲得相應(yīng)的數(shù)據(jù)了。
規(guī)則引擎的結(jié)果可以通過topic來進行再分發(fā)。
目前只有實時引擎是java的,因為性能要求苛刻,其他模塊采用python開發(fā)。
上圖只是個例子,來簡要說明babel是如何支撐一個分布式數(shù)據(jù)計算系統(tǒng)的。實際的系統(tǒng)使用了更多的語義,也更加的復(fù)雜。不過借助于Babel的協(xié)助,整個系統(tǒng)在實現(xiàn)和運維上已經(jīng)很大程度上減輕了復(fù)雜程度。
2 水平擴展的web系統(tǒng)
第二個例子是我們曾經(jīng)做過的SAAS平臺私有化案例,是我們早期SAAS平臺的極簡版本。
圖畫的略凌亂了些:
系統(tǒng)主架構(gòu)是用haproxy做負載均衡,發(fā)到我們的兩臺主機上。
兩臺主機內(nèi)部完全相同,右邊主機內(nèi)部組件沒有畫全。
每臺主機有內(nèi)部的nginx,load balance到本機器內(nèi)部的諸多python web server 上。
python web server直接讀取本地的nosql數(shù)據(jù)庫。
寫數(shù)據(jù)時,由于寫請求sharding到兩臺機器上,所以我們有個topic的service來處理nosql數(shù)據(jù)寫入,保證每個寫入操作都寫到兩臺機器上,每臺機器的nosql始終存有全量的最新數(shù)據(jù)。
由于客戶要求落地關(guān)系型數(shù)據(jù)庫,所以通過shuffle再將寫請求分散開,統(tǒng)一寫入mysql中。
在這個系統(tǒng)中,我們成功的利用babel建立了自己的一致性框架,從而避免了去使用db做數(shù)據(jù)一致性;同時由于對等的服務(wù)器架構(gòu),在部署維護上省掉了很多事情。
框架運維整個框架,我們都準備了統(tǒng)一的metrics體系去做監(jiān)控和報警(實際上metrics系統(tǒng)本身的跨機房屬性反而是通過babel來實現(xiàn)),詳盡的監(jiān)視了RPC的某個環(huán)節(jié),之前有過我們監(jiān)控的文章,這里就不重復(fù)了。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/45549.html
摘要:研發(fā)通訊框架,以及其支撐的其他框架,比如監(jiān)控報警等。這個是最重要的角色。目前的配置與分發(fā)還不能做到自動化,有手工工作量。完成自動化發(fā)布部署,將整個系統(tǒng)做一個統(tǒng)一的整體。研究彈性伸縮方面的非功能性擴展。考慮增加熔斷等自我保護機制。 showImg(https://segmentfault.com/img/bVQ2BQ?w=400&h=277); (圖片源自網(wǎng)絡(luò)) 4框架生態(tài) 實際上,在做...
摘要:概述在簡易框架需求與設(shè)計這篇文章中已經(jīng)給出了協(xié)議的具體細節(jié),協(xié)議類型為二進制協(xié)議,如下協(xié)議的解碼我們稱為,編碼我們成為,下文我們將直接使用和術(shù)語。直接貼代碼,參考前文提到的協(xié)議格式閱讀以下代碼協(xié)議編碼器 概述 在《簡易RPC框架:需求與設(shè)計》這篇文章中已經(jīng)給出了協(xié)議的具體細節(jié),協(xié)議類型為二進制協(xié)議,如下: ---------------------------------------...
閱讀 3441·2023-04-25 23:25
閱讀 2069·2021-11-12 10:36
閱讀 2816·2019-08-30 12:47
閱讀 2037·2019-08-29 18:45
閱讀 435·2019-08-29 17:28
閱讀 1785·2019-08-29 17:15
閱讀 1707·2019-08-29 16:05
閱讀 1405·2019-08-29 14:17