Jack Jiang

          我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
          posts - 506, comments - 13, trackbacks - 0, articles - 1
          本文由釘釘技術(shù)專家嘯臺、萬泓分享,為了獲得更好的閱讀效果,本文已對內(nèi)容進(jìn)行少修訂和重新排版。

          1、引言

          釘釘后端架構(gòu)的單元化工作從2018年開始到今年,已經(jīng)是第五個年頭了。五年的時間,釘釘單元化迭代了三個版本,從最初的毛頭小子,到達(dá)今年已經(jīng)小有成就。

          我們在進(jìn)行單元化架構(gòu)建設(shè)的過程中,除了網(wǎng)上能找到的屈指可數(shù)的文章外,可以直接使用的系統(tǒng)更是乏善可陳,使我們不得不從最基礎(chǔ)的系統(tǒng)開始造輪子,極大的影響建設(shè)效率。幸運的是,近幾年云原生技術(shù)的興起,讓我們能復(fù)用很多基礎(chǔ)設(shè)施,進(jìn)而快速提升我們的單元化建設(shè)能力,助力釘釘?shù)陌l(fā)展。

          今天想借此文和大家分享我們在釘釘單元化架構(gòu)實施過程中的心路歷程和一些最佳實踐。因涉及的技術(shù)和業(yè)務(wù)面太廣,本文的分享無法做到面面俱到,主要是想在同路人中形成共鳴,進(jìn)而能復(fù)用一些架構(gòu)或子系統(tǒng)的設(shè)計和實現(xiàn)思路。

          學(xué)習(xí)交流:

          (本文同步發(fā)布于:http://www.52im.net/thread-4122-1-1.html

          2、系列文章

          本文是系列文章的第 10 篇,總目錄如下:

          3、術(shù)語概念

          本文內(nèi)容中使用了一些專有的技術(shù)名詞,為了方便大家理解,我把關(guān)鍵的幾個術(shù)語概念的縮寫及其含義專門列出來,供大家參考。

          主要是以下幾個

          • 1)Geo:釘釘專有化部署單位,解決數(shù)據(jù)合規(guī)需求,Geo間數(shù)據(jù)按需互通,并且互通數(shù)據(jù)在Geo內(nèi)部做鏡像拷貝,解決兩化問題;
          • 2)Unit: Geo內(nèi)部資源物理分區(qū)隔離的最小單位,解決Geo內(nèi)的容災(zāi)和容量的問題;
          • 3)L0:客戶端路由,決定了用戶客戶端接入釘釘服務(wù)器的所屬單元,用戶長連接所在的邏輯單元,起到連接加速作用。用戶接入單元;
          • 4)L1:接入層路由,以用戶為維度進(jìn)行調(diào)度,即用戶操作發(fā)生的單元。用戶歸屬單元;
          • 5)L2:業(yè)務(wù)層路由,以業(yè)務(wù)資源為維度進(jìn)行調(diào)度,大部分的業(yè)務(wù)資源所在單元應(yīng)該和用戶調(diào)度單元一致,但一些業(yè)務(wù)無法按照用戶劃分單元,如IM的會話,音視頻的會議。 業(yè)務(wù)歸屬單元;
          • 6)DMB:負(fù)責(zé)釘釘應(yīng)用跨單元RPC調(diào)用的轉(zhuǎn)發(fā),可以認(rèn)為是釘釘單元化RPC路由中間件;
          • 7)DMR:負(fù)責(zé)釘釘應(yīng)用跨單元MQ消息的轉(zhuǎn)發(fā),可以認(rèn)為是釘釘單元化MQ路由中間件;
          • 8)DTIM:釘釘IM系統(tǒng)。

          4、單元化架構(gòu)1.0版:合規(guī)驅(qū)動下的部署架構(gòu)

          2018年,部分大客戶出于法律政策、商業(yè)機密數(shù)據(jù)存儲的要求,要求釘釘?shù)臄?shù)據(jù)存儲、訪問接入、服務(wù)部署需要在其信任的區(qū)域內(nèi)。既需要滿足其數(shù)據(jù)存儲私有化要求,同時需要滿足跨地區(qū)網(wǎng)絡(luò)的rt性能要求。

          于是我們結(jié)合阿里云機房部署位置、物理距離、用戶數(shù)據(jù)安全等方面出發(fā),釘釘在客戶的阿里云機房內(nèi)建設(shè)了一個單元,將通訊錄、IM信息等企業(yè)數(shù)據(jù)單獨存儲在客戶機房。

          我們通過一條專線,將兩個機房邏輯串聯(lián)到一起,內(nèi)部通過DMB/DMR系統(tǒng),實現(xiàn)了請求互通,這就是釘釘單元化架構(gòu)的1.0版。

          1.0版比較簡單,純粹是業(yè)務(wù)驅(qū)動,和支付寶單元化建設(shè)的初衷——“容災(zāi)驅(qū)動”有較大區(qū)別。兩個站點通過UID分段,將用戶劃分為中心用戶和專有用戶。

          上圖只是一個簡化的邏輯結(jié)構(gòu),內(nèi)部實現(xiàn)遠(yuǎn)比上圖復(fù)雜,但是1.0建設(shè)主要是從0到1,和大多數(shù)異地多活的系統(tǒng)較相似,這里就只簡單的和大家分享一下。

          5、單元化架構(gòu)2.0版:逼出來的容量架構(gòu)

          2020年是一個特殊的年份,由于疫情的原因,帶給大家非常多的改變,其中也包括釘釘。

          由于在線辦公與教育流量的突增,開年第一天上班就給釘釘一個下馬威,平峰的流量已經(jīng)和除夕跨年的持平,但是和除夕不同的是這個流量是持續(xù)的,即使節(jié)前準(zhǔn)備了三倍容量,也抵擋不住流量對系統(tǒng)的沖擊。只能借助阿里云的能力,不斷的擴容。

          但是每天將近30%的流量增幅,單純的擴容也能難保障服務(wù)的連續(xù)性,最終也遇到了擴無可擴的場景,張北機房沒有機位了,有機器資源但是沒有機位讓我們有力無處使。我們不得不不斷進(jìn)行系統(tǒng)優(yōu)化,同時借助限流、降級、雙推等措施,勉強抗住了流量的最高峰。

          疫情之前,我們一直在做高可用,但是這個高可用主要集中在容災(zāi)機制上,比如搭建容災(zāi)單元。如同支付寶一樣,是因為當(dāng)時光纖被挖斷;又比如銀行的兩地三中心架構(gòu),是擔(dān)心某一個地域由于天災(zāi)或者戰(zhàn)爭導(dǎo)致數(shù)據(jù)丟失。疫情的流量給我們上了一課,僅僅關(guān)注容災(zāi)是不夠的,特別是釘釘?shù)腄AU從千萬走向億級別之后,更需要在容量上做出提前規(guī)劃。

          正因如此,我們認(rèn)為“容量架構(gòu)不是設(shè)計出來而是真真切切被逼出來的”,所以容量架構(gòu)就成為我們單元化核心要素之一。

          容量架構(gòu)是將流量劃分到不同單元,每個單元承載各自的流量。容災(zāi)架構(gòu)是單元異常時,能保障核心的能力可用,也可以將流量動態(tài)調(diào)度到別的單元,實現(xiàn)服務(wù)的快速恢復(fù)。

          因此釘釘單元化進(jìn)入了2.0時代,專注于容量和容災(zāi)的建設(shè)。

          6、2.0版是基于什么維度進(jìn)行流量劃分的?

          要實現(xiàn)流量的劃分,必然要基于一個維度進(jìn)行劃分,一部分到A單元,一部分到B單元。

          釘釘單元化架構(gòu)也是參考了淘系和支付寶的單元化架構(gòu),前兩者都是基于UID劃分,釘釘單元化的第一個版本其實也是一樣的,基于UID做拆分。

          但是當(dāng)我們設(shè)計容量架構(gòu)時,發(fā)現(xiàn)基于UID劃分無法解決我們的容量問題。

          以IM為例:一條消息其實屬于聊天雙方的,群聊亦是如此。用戶能和任意一個人聊天,這樣我們根本無法找到一個切入點來劃分流量,強行按照UID拆分,必然導(dǎo)致一個用戶的消息出現(xiàn)在N個單元,單元的自封閉就無法做了。

          也有同學(xué)會說:為什么消息不按照每個人存儲,這不就能按照UID劃分了嗎?結(jié)論是不行。首先這個消息變成了寫擴散,持久化的時候會變成多單元寫,其次是成本翻倍,在DTIM這種過億規(guī)模的場景這條路走不通。這里可以多說一點,因為這個觀點來之不易,大家都知道,人是有慣性的,既然淘寶、支付寶甚至是微信都是UID劃分,為什么釘釘要特立獨行?當(dāng)時我們團隊受到了絕大部分釘釘技術(shù)團隊的挑戰(zhàn),持續(xù)長達(dá)將近一個月的技術(shù)選型的“爭吵”,最終還是達(dá)成了一致意見。

          DTIM主要有3個維度,分別是UID、會話(CID)、消息。其中會話和消息是綁定的,而系統(tǒng)中最大量的是消息,按照第一性原則來看,一定要將消息劃分開來,才能做到將容量劃分開來的效果。

          我們再來看看音視頻,是按照房間維度組織流量和數(shù)據(jù)的,和IM又完全不同。

          同樣,文檔其實更適合按照企業(yè)維度來劃分。

          不同的業(yè)務(wù)擁有不同的維度,因此我們認(rèn)為:單元化最重要的找到自身“最大”的業(yè)務(wù)維度,將這個維護(hù)拆分,才能實現(xiàn)單元的橫向擴展,我們稱之為“業(yè)務(wù)路由”。

          回頭來看:我們之前其實是進(jìn)入了思考誤區(qū),以為淘系和支付寶都是UID維度,我們也要這個維度,其實UID正是前者的業(yè)務(wù)維度,比如訂單,也是圍繞用戶,并不會有交集的情況,會話就是IM的劃分維度,因此做單元化之前要先找到屬于自己的業(yè)務(wù)維度。

          7、2.0版是如何實現(xiàn)IM消息的全局路由能力的?

          7.1概述

          UID路由有個最大的好處,就是可以按照UID分段,能實現(xiàn)高效的靜態(tài)路由,也不用擔(dān)心多單元之間的一致性問題。但是這種分段路由局限性也比較明顯,需要預(yù)先分配,單元之間動態(tài)調(diào)度流量和數(shù)據(jù)成本極高,而且只能支持這種數(shù)值+順序的場景。

          在釘釘?shù)膱鼍爸校袝捑S度、房間維度、企業(yè)維度等等,想簡單采用這種預(yù)分段機制難以滿足業(yè)務(wù)需求。因此我們需要構(gòu)建一個業(yè)務(wù)路由系統(tǒng)(RoutingService),實現(xiàn)消息流量的精確路由。

           

           以IM為例:每次消息的發(fā)送,在單元化框架層面,會通過消息的會話(CID),查詢路由信息,如果是本單元,流量下行并持久化;如果是非本單元,路由到對應(yīng)的單元中。

          下圖是三個會話:分別是cid:1001、cid:1002、cid:1003,三個會話隸屬不同單元,不管用戶從哪個單元發(fā)送消息,都會路由到會話所在的單元。比如:用戶在Unit B的cid:1001 中發(fā)送消息,當(dāng)消息進(jìn)入Receiver之后,會先查詢此cid:1001所在的單元,發(fā)現(xiàn)是Unit A,路由框架將請求轉(zhuǎn)到A單元,消息在A單元持久化并通過A單元的同步協(xié)議,將數(shù)據(jù)推送到客戶端。

           

           

           從上圖可知:每次消息發(fā)送,都要查詢路由服務(wù),DTIM百萬的峰值,對路由必然會帶來超大的壓力,同時我們能發(fā)現(xiàn),路由數(shù)據(jù)在多單元實現(xiàn)一致性是一個巨大的挑戰(zhàn)。

          7.2邊緣計算:端到端路由

          在DTIM的場景中,會話的路由信息幾乎不會變更,只有當(dāng)我們決定將某些超大的會話或者企業(yè)騰挪到新單元時,才會發(fā)起路由的變更,因此會話的路由信息幾乎可以認(rèn)為是恒定不變的。那么每次查詢路由服務(wù)端,效費比太低,是極大的浪費。

          既然路由信息幾乎不可變,是否將路由信息緩存呢?最常見的是使用一個集中式的Cache系統(tǒng),緩存Hot的會話,我們也是這么做的,但是這么做還是不夠,一旦Cache系統(tǒng)失效,DTIM還是會出現(xiàn)大面積故障,而且這個百萬級的請求對Cache也是一個極大的壓力。

          考慮到釘釘有強大的客戶端,借用邊緣計算的思路,我們將用戶的會話數(shù)據(jù)緩存到客戶端。對于客戶端來說,也只用緩存用戶自身最熱的N會話路由數(shù)據(jù),消息發(fā)送時,通過Header將路由數(shù)據(jù)攜帶到服務(wù)端,服務(wù)端路由SDK只要做合法性和續(xù)約即可,這樣就將路由流量降低了95%以上。當(dāng)路由服務(wù)出現(xiàn)異常時,還可以繼續(xù)使用客戶端路由,將路由的可用性提升到一個新的高度。

          SDK本地會依據(jù)上行請求的返回中是否有新的路由信息,進(jìn)而更新客戶端路由。同時可以借助釘釘有主動下推的能力,通過同步協(xié)議將新的路由信息主動推送給客戶端,使會話遷移做到更平順。

          7.3計算下沉:多單元一致性


          對于新會話:比如小明要創(chuàng)建一個群聊,是應(yīng)該創(chuàng)建在那個單元呢?

          如果在A單元創(chuàng)建了,當(dāng)會話消息來到B單元,系統(tǒng)怎么能第一時間知道會話已經(jīng)在被綁定到A單元。

          這里一般的方式有兩種

          • 1)單元之間的存儲系統(tǒng)采用類似DTS的機制進(jìn)行異步同步,這種機制有秒級延遲;
          • 2)在應(yīng)用層主動同步,比如接入消息隊列。


          這兩種方式由于都是異步的原因,都會出現(xiàn)不一致的問題,如果會話同時被綁定在兩個單元,邏輯上會導(dǎo)致用戶的歷史消息丟失,這個是不能接受的。

          多地域(Region)數(shù)據(jù)同步其實是通用的技術(shù)挑戰(zhàn),我們認(rèn)為存儲系統(tǒng)提供是最好的方式,正如Google的Spanner一樣,這樣對我們上層才是最友好的方式。

          因此我們找到了存儲的OTS、Nuwa團隊一起共建了GlobalTable。GlobalTable的核心原理還是借助Nuwa的一致性組,組分布在多個地域,采用多數(shù)派寫入成功即返回的原理,做到20ms以內(nèi)的一致性寫。

          8、2.0版的容災(zāi)能力

          釘釘單元化的容災(zāi)能力是深度結(jié)合釘釘?shù)臉I(yè)務(wù)層場景落地的,和淘系支付寶等有明確的區(qū)別。

          以DTIM為例,最大的特點是當(dāng)服務(wù)單元異常時,服務(wù)側(cè)仍能提供最核心的服務(wù),保障最基本的能力。本質(zhì)上是由于DTIM是最終一致性系統(tǒng),可以短暫允許部分環(huán)節(jié)失敗。

          可以看一下DTIM發(fā)送消息的容災(zāi)場景。當(dāng)某個單元完全不可用的情況下,用戶消息發(fā)送鏈路通過降級為local模式,在本地校驗非本單元會話數(shù)據(jù)通過之后直接做消息發(fā)送,processor遇到非本單元的會話消息數(shù)據(jù)可以做單元間投遞做數(shù)據(jù)回放,本地是否落庫可選,同步協(xié)議推送不必區(qū)分是否為本單元會話消息數(shù)據(jù)直接通過本單元的topic推送給客戶端,配合用戶無狀態(tài)快速遷移能力,單元間可以實現(xiàn)真正的分鐘級別容災(zāi)切換能力。

          9、2.0版的成果與突破

          以上是釘釘單元化2.0提供給應(yīng)用的核心能力,在滿足容災(zāi)和容量設(shè)計需求之后,釘釘單元化給應(yīng)用帶來了更多的能力和想象空間。

          比如:

          • 1)快速遷移:當(dāng)某一地域資源不足時,釘釘單元化可以將業(yè)務(wù)快速的從A單元遷移到B單元;
          • 2)常態(tài)化切流:比如新建的教育會話,可以放到獨立的單元;
          • 3)熱點治理:當(dāng)前某一個會話過熱,特殊時期可以遷移到獨立集群;
          • 4)SLA:滿足不同的VIP客戶需求,基于不同的SLA和售賣價格,將VIP客戶放到對應(yīng)地單元。

          核心還是我們擁有單元化能力之后,實現(xiàn)了多單元流量的快速調(diào)度,為業(yè)務(wù)解決了后顧之憂。

          10、2.0版在新時代面臨的新挑戰(zhàn)

          10.1魚和熊掌不可兼得

          2022年對釘釘來說是成本之年,成本的壓力不光落到了團隊,還落到了每個人身上。

          正如存儲的CAP理論是一樣的,我們同時只能滿足兩個維度,對于流量(性能P)、成本(C)、體驗(E)也是一樣,在流量不可預(yù)知和干預(yù)的情況下,選擇成本必然導(dǎo)致體驗受損,反之選擇體驗,必然導(dǎo)致成本升高。進(jìn)入下半年,疫情反復(fù)帶來流量的反復(fù),為了實現(xiàn)可控的教育成本,只能在高峰期降級部分能力,這又導(dǎo)致體驗受損,這段時間的工單量可以窺見一斑。

          流量是用戶側(cè)觸發(fā)的,我們無法干預(yù),只能在成本和體驗之間尋求平衡。和前面提及的一樣,為了減小成本的消耗這就導(dǎo)致我們在擴容和縮容之間疲于奔命,反應(yīng)不及時甚至有故障的危險,這種機制不可取也不可持續(xù)。到底是要流量與成本,還是要流量與體驗,給我們技術(shù)團隊帶來了巨大的挑戰(zhàn)和矛盾。

          10.2商業(yè)化路在何方

          當(dāng)前釘釘為支持大客戶提供了多種解決方案,專業(yè)釘釘、專屬存儲與打包、專有釘釘。

          專屬釘釘通過APP專屬化以及部分專屬功能,比如為一個企業(yè)定制一個擁有獨立Logo的APP,能滿足一般的中大型客戶的業(yè)務(wù)訴求。

          對于大型以及超大型客戶,我們提供專有釘釘,提供專有化輸出,完全隔離的方案,比如浙政釘。

          伴隨著釘釘?shù)纳虡I(yè)化進(jìn)入深水區(qū),客戶對釘釘提出了新的訴求,特別是數(shù)據(jù)安全與歸屬、互聯(lián)互通、完整的能力棧等訴求,當(dāng)前釘釘輸出產(chǎn)品形態(tài)都無法同時地滿足以上需求。

          前幾年互聯(lián)網(wǎng)上出現(xiàn)的幾起數(shù)據(jù)安全事件,數(shù)據(jù)丟失與泄露,未經(jīng)客戶授權(quán)私自訪問客戶數(shù)據(jù),讓大多數(shù)客戶不信任服務(wù)提供商,即使服務(wù)商的安全能力已經(jīng)是業(yè)界一線能力。其實這個是可以理解的,數(shù)據(jù)即客戶的生命線,數(shù)據(jù)無法在自身可控范圍內(nèi),特別是對于很多特殊行業(yè),這是無法接受的,自身性命豈能假手于人。專屬釘釘在面臨這種客戶時,前線售賣同學(xué)是無能為力。

          那么很多同學(xué)肯定會提“如果專屬釘釘滿足不了需求,我們專有釘釘不是能解決這些問題嗎?”,其實單單從訴求來看,專有釘釘場景是切合客戶的業(yè)務(wù)訴求,提供完全獨立運行環(huán)境、可控的數(shù)據(jù)安全。但是專有釘釘由于其獨特的架構(gòu)帶來高昂的售價以及后期的運維代價,對于超大型的客戶來說也難以承擔(dān)如此高的成本。對于釘釘自身來說,從研發(fā)到后續(xù)運維,維護(hù)一套獨立體系也難以在客戶側(cè)大面積推廣。

          11、單元化架構(gòu)3.0版:混合云架構(gòu)

          11.1概述

          釘釘單元化經(jīng)過四年的發(fā)展,在容災(zāi)和容量上做出一定的積淀,同時完成了一些核心技術(shù)的積累。

          當(dāng)整體架構(gòu)成熟之后,我們也在思考,單元化能否從技術(shù)架構(gòu)升級為業(yè)務(wù)架構(gòu),比如搭建獨立的高可用單元,按照售賣的SLA提供給VIP客戶,支持釘釘商業(yè)化的發(fā)展。

          同時我們在云原生逐步發(fā)力,將部分核心應(yīng)用放到云上,經(jīng)過這一年多的運行,遇到了新的挑戰(zhàn),但更獲得云下無法獲得的計算彈性能力,云上的彈性對云下是一個降維打擊,從一個新的方向解決計算問題。

          如上文提到的兩個核心挑戰(zhàn),釘釘單元化同樣面臨這個問題,在持續(xù)的發(fā)展中找到了一個合適的架構(gòu)方向。

          基本思路是:

          • 1)云下作為基本盤,保障核心流量的問題,畢竟云下經(jīng)過集團多年的打磨,不管是穩(wěn)定性還是流程的合理性都有保障;
          • 2)云上應(yīng)對高漲異常的流量,比如和疫情正相關(guān)的教育流量,既保證了服務(wù)的穩(wěn)定性,又能充分利用云上彈性能力,在提供完整能力的前提下做到一個相對較低的成本。

          其次是升級Geo概念:

          • 1)將Geo作為一個獨立的業(yè)務(wù)域,實現(xiàn)Geo級別完全獨立部署,分布式云模式;
          • 2)同時Geo之間按需互通,從研發(fā)體系上能做到一套代碼。

          因此,釘釘單元化來到了3.0版本,我們稱之為釘釘單元化混合云架構(gòu)。

          混合云主要是從兩個維度來看:

          • 第一:是云上云下,我們認(rèn)為云上云下并不是取代的關(guān)系,而是相互補充的關(guān)系,是一個長期的狀態(tài),正如很多大客戶隨著規(guī)模的持續(xù)擴張,最終依賴的部分核心能力必然走向自研道理一樣,這能做成本的進(jìn)一步降低,所以架構(gòu)是一個混合云架構(gòu);
          • 第二:業(yè)務(wù)架構(gòu)上也是混合云架構(gòu),通過不同的Geo,將不同的業(yè)務(wù)邏輯上聚合到一起,構(gòu)建起一張釘釘?shù)拇缶W(wǎng),不同Geo按需互通,實現(xiàn)了業(yè)務(wù)架構(gòu)的混合。

          3.0從系統(tǒng)架構(gòu)上相對于2.0,最大的區(qū)別就是云原生技術(shù)的運用和互通網(wǎng)關(guān)的建立。

          11.2云原生技術(shù) :抵抗系統(tǒng)架構(gòu)熵增的有效手段

          近幾年,互聯(lián)網(wǎng)圈最火的技術(shù)莫過于以Docker為代表的云原生技術(shù)最為火熱,各大云廠商也都在不遺余力的推廣云原生技術(shù)以及對應(yīng)的產(chǎn)品。同時釘釘服務(wù)過億DAU的客戶,面對各種可靠性、服務(wù)連續(xù)性、并發(fā)、容災(zāi)等技術(shù)挑戰(zhàn),也都走到了現(xiàn)有技術(shù)的邊界。

          所以我們也在不斷吸收新的技術(shù)和架構(gòu),希望從體系與架構(gòu)上降低我們的技術(shù)復(fù)雜度,以抵抗熵增。

          我們在2021年底啟動了云原生升級戰(zhàn)略,升級云原生技術(shù)并不是為了技術(shù)而升級,而是切實面臨巨大的技術(shù)挑戰(zhàn)。

          1)首先我們面臨多語言的挑戰(zhàn):

          我們以IM為例,IM的核心邏輯都是使用C++構(gòu)建,但是我們常用的中間件三大件:存儲、緩存、異步隊列,其中緩存和異步隊列在C++客戶端上長期建設(shè)不足,導(dǎo)致IM長期在使用低版本。

          低版本由于長時間缺乏維護(hù),經(jīng)常會出現(xiàn)異常,比如隊列假死、消費不均等,導(dǎo)致我們自己不得不親自上陣修改SDK的代碼,以致最后難以使用到產(chǎn)品的新能力,阻礙IM服務(wù)能力的提升。

          2)其次是多產(chǎn)品多云的挑戰(zhàn):

          我們以阿里云為例,數(shù)據(jù)庫類目下的產(chǎn)品,從類別上就有關(guān)系數(shù)據(jù)庫、NoSQL數(shù)據(jù)庫、數(shù)倉等等,還有存儲也是一樣。

          對于我們上層業(yè)務(wù),其實絕大部分服務(wù)都只依賴了底層的CURD,這么多產(chǎn)品,每次對接一個產(chǎn)品都要開發(fā)一輪。

          配置系統(tǒng)也是一樣,彈內(nèi)有Diamond,云上有Nacos、Mse,K8s有自己的Configmap等,而且這些配置系統(tǒng)不像數(shù)據(jù)庫有標(biāo)準(zhǔn),而是百花齊放,但是這樣卻苦了我們使用者。

          這些內(nèi)容不是我們的核心路徑,浪費大把時間在各種產(chǎn)品接口的適配上,明顯拖累了釘釘?shù)陌l(fā)展。

          3)最后就是通用的流量治理挑戰(zhàn):

          釘釘很多系統(tǒng)都是最終一致的系統(tǒng),IM就是典型的最終一致系統(tǒng),這類系統(tǒng)和強同步系統(tǒng)在架構(gòu)設(shè)計有一個明顯的區(qū)別,強一致系統(tǒng)如果遇到失敗,必須要持續(xù)重試直到成功,所以一般編程上都是重試+退避。

          但是最終一致系統(tǒng)不是,這類系統(tǒng)允許部分節(jié)點失敗,不要阻礙其他流程,失敗的流量通過一個異步回旋的隊列,將數(shù)據(jù)逐步回放回來即可。這種回旋需要借助異步隊列,而且要設(shè)計各種消費機制,比如限速、比如丟棄等等,這是一個通用的邏輯,但是每個業(yè)務(wù)方或多或少都在實現(xiàn)自己的回旋系統(tǒng),重復(fù)的造輪子。又比如各種故障注入,單元化路由流量等等,要想擁有這個能力,團隊不得不投入人力研發(fā)。

          在對付架構(gòu)復(fù)雜度上,我們主要從兩個維度來屏蔽復(fù)雜度。

          首先代碼層面我們選擇了DDD模式,我們使用DDD分層核心是把對外系統(tǒng)的依賴全部收攏到Infrastructure這一層,全部采用純虛函數(shù)(Interface)對外提供接口。屏蔽底層中間件差異和細(xì)節(jié)。

          在架構(gòu)上采用Sidecar的模式,類似于Dapr的思想,通過標(biāo)準(zhǔn)的GRPC和PB實現(xiàn)應(yīng)用與中間件解耦。Sidecar中集成了各種中間件、配置系統(tǒng)、灰度系統(tǒng)等,等價實現(xiàn)了應(yīng)用和中間件的解耦。上文中提到的不管是多語言挑戰(zhàn)、多云多產(chǎn)品的挑戰(zhàn)、重復(fù)造輪子等問題,都能很好的解決。

          11.3互通網(wǎng)關(guān) :混合架構(gòu)的基石

          云上云下互通,或者說多個云賬戶VPC之間的互通,我們常見的有兩種方案:

          • 1)其一是VPC直接打通,讓多個VPC之間形成一個大的局域網(wǎng),RealServer實現(xiàn)點對點互通;
          • 2)其一是中間搭建一個負(fù)載均衡器,通過暴露EIP實現(xiàn)互通。

          兩個方案都有自己的優(yōu)缺點。

          對于方案一:打通的VPC涉及到IP規(guī)劃,如果前期沒有合理規(guī)劃,后續(xù)很難打通;還有這種方案有水桶短板安全問題,一旦一個VPC被攻破,這張網(wǎng)也被攻破;但是對于內(nèi)部的應(yīng)用來說架構(gòu)就比較簡單,可以僅僅借助K8s DNS service就能做到服務(wù)發(fā)現(xiàn)。

          對于方案二:最大的缺點就是中間有一個集中式的負(fù)載均衡,需要申請獨立的LB才可訪問;但是這種方案隔離性好。

          對于釘釘單元化來說,涉及N個業(yè)務(wù)方,N * M個應(yīng)用,對應(yīng)X個VPC,要想VPC之間打通,幾乎沒有可能性,而且VPC打通,還面臨應(yīng)用之間的安全性問題。要實現(xiàn)Geo之間互通,環(huán)境之間的隔離性是基本要求,與此同時,我們也要考慮到系統(tǒng)的可擴展性,所以我們必須要構(gòu)建一套獨立的流量網(wǎng)關(guān),實現(xiàn)流量加密、尋址、轉(zhuǎn)發(fā)等通用能力。

          釘釘互通網(wǎng)關(guān)是構(gòu)建在Envoy之上的系統(tǒng),雙向Ingress和Egress,支持GRPC和釘釘自研協(xié)議。具備流量管理、傳輸加密、單元尋址等能力。釘釘單元化借助互通網(wǎng)關(guān)的能力,再配合全局流控系統(tǒng),我們可以在多單元之間實現(xiàn)精確的流量控制和調(diào)度。

          12、寫在最后

          伴隨著專屬集群的持續(xù)輸出,客戶對專屬的場景需求會越來越多,需要我們投入更多的人力持續(xù)的建設(shè)。

          比如:

          • 1)在架構(gòu)側(cè):首先是Sidecar持續(xù)強化,支持更多的中間件和環(huán)境,提供不同維度的安全能力,滿足客戶和應(yīng)用的安全需求;
          • 2)在運維側(cè):我們需要構(gòu)建多Geo管理能力,完善Geo和單元之間流量快速調(diào)度能力,提供自動化的自檢系統(tǒng)等;
          • 3)在交付側(cè):如果實現(xiàn)快速交付,比如是否能做到新應(yīng)用一周完成單元化改造,新Geo一天部署完成。這些挑戰(zhàn)都是接下來我們要重點投入的方向。

          對于標(biāo)準(zhǔn)釘釘來說,這個是我們的基本盤,一個穩(wěn)定可靠且低成本的釘釘是我們持之以恒的目標(biāo),接下來我們會加大云上流量的占比,充分的借助云上彈性能力,實現(xiàn)可控的成本。

          今天我們只是站在釘釘?shù)慕嵌壬蠏伭艘粋€“磚”,希望在異地多活這個領(lǐng)域激起一層浪花,歡迎大家一起討論。

          13、相關(guān)資料

          [1] 現(xiàn)代IM系統(tǒng)中聊天消息的同步和存儲方案探討

          [2] 企業(yè)級IM王者——釘釘在后端架構(gòu)上的過人之處

          [3] 深度解密釘釘即時消息服務(wù)DTIM的技術(shù)設(shè)計

          [4] 釘釘——基于IM技術(shù)的新一代企業(yè)OA平臺的技術(shù)挑戰(zhàn)(視頻+PPT)

          [5] 企業(yè)微信的IM架構(gòu)設(shè)計揭秘:消息模型、萬人群、已讀回執(zhí)、消息撤回等

          [6] IM系統(tǒng)的MQ消息中間件選型:Kafka還是RabbitMQ?

          [7] 深度揭密RocketMQ在釘釘IM系統(tǒng)中的應(yīng)用實踐

          (本文同步發(fā)布于:http://www.52im.net/thread-4122-1-1.html



          作者:Jack Jiang (點擊作者姓名進(jìn)入Github)
          出處:http://www.52im.net/space-uid-1.html
          交流:歡迎加入即時通訊開發(fā)交流群 215891622
          討論:http://www.52im.net/
          Jack Jiang同時是【原創(chuàng)Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
          本博文 歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明出處(也可前往 我的52im.net 找到我)。


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          Jack Jiang的 Mail: jb2011@163.com, 聯(lián)系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 齐齐哈尔市| 临湘市| 财经| 新河县| 平乡县| 湄潭县| 营口市| 汝南县| 广西| 浮山县| 弋阳县| 金沙县| 泸西县| 喀什市| 建瓯市| 郎溪县| 普定县| 澄迈县| 乌兰县| 崇左市| 华阴市| 定兴县| 青神县| 通山县| 靖江市| 延川县| 濮阳县| 汕头市| 辽中县| 河间市| 渑池县| 松原市| 广元市| 莲花县| 论坛| 青田县| 金沙县| 图木舒克市| 鹤庆县| 乌鲁木齐市| 张家口市|