當前位置:首頁 » 服務存儲 » 新一代微信後台數據存儲架構設計
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

新一代微信後台數據存儲架構設計

發布時間: 2022-11-13 11:02:43

1. 微信第三方平台 後台mysql 用戶表怎麼設計

說起用戶表,大概是每個應用/網站立項動工(碼農們)考慮的第一件事情。用戶表結構的設計,算是整個後台架構的基石。如果基石不穩,待到後面需求跟進了發現不能應付,回過頭來反復修改用戶表,要大大小小作改動的地方也不少。與其如此,不妨設計用戶表之初就考慮可拓展性,爭取不需要太多額外代價的情況下一步到位。
先前設計:
id
username
password
用戶名加上密碼,解決簡單需求,留個id作為其他表的外鍵。當然,那時候密碼還可能是明文存儲,好點的知道md5。
後來呢,隨著業務需求的拓展,要加個用戶狀態 status 判斷用戶是否被封禁,注冊時間和注冊IP地址、上次登錄時間和IP地址備查(並衍生出登錄記錄表,用來判斷是否異地登錄等,在此不表),用戶角色/許可權 role (又衍生出用戶角色許可權關系,還是另文討論),業務也需要個人的個人信息如真實姓名、地址等也一股腦往上添加,現在形成了一個很完整的用戶關系表。

2. 關於微信的架構問題

最初的方案是客戶端記錄一個本地數據的快照(Snapshot),需要同步數據時,將Snapshot帶到伺服器,伺服器通過計算Snapshot與伺服器數據的差異,將差異數據發給客戶端,客戶端再保存差異數據完成同步。不過這個方案有兩個問題:一是Snapshot會隨著客戶端數據的增多變得越來越大,同步時流量開銷大;二是客戶端每次同步都要計算Snapshot,會帶來額外的性能開銷和實現復雜度。

幾經討論後,方案改為由服務計算Snapshot,在客戶端同步數據時跟隨數據一起下發給客戶端,客戶端無需理解Snapshot,只需存儲起來,在下次數據同步數據時帶上即可。同時,Snapshot被設計得非常精簡,是若干個Key-Value的組合,Key代表數據的類型,Value代表給到客戶端的數據的最新版本號。Key有三個,分別代表:帳戶數據、聯系人和消息。這個同步協議的一個額外好處是客戶端同步完數據後,不需要額外的ACK協議來確認數據收取成功,同樣可以保證不會丟數據:只要客戶端拿最新的Snapshot到伺服器做數據同步,伺服器即可確認上次數據已經成功同步完成,可以執行後續操作,例如清除暫存在服務的消息等等。

此後,精簡方案、減少流量開銷、盡量由伺服器完成較復雜的業務邏輯、降低客戶端實現的復雜度就作為重要的指導原則,持續影響著後續的微信設計開發。記得有個比較經典的案例是:我們在微信1.2版實現了群聊功能,但為了保證新舊版客戶端間的群聊體驗,我們通過伺服器適配,讓1.0版客戶端也能參與群聊。

3. 定型了後台架構



圖 2 微信後台系統架構

微信後台使用三層架構:接入層、邏輯層和存儲層。

接入層提供接入服務,包括長連接入服務和短連接入服務。長連接入服務同時支持客戶端主動發起請求和伺服器主動發起推送;短連接入服務則只支持客戶端主動發起請求。

邏輯層包括業務邏輯服務和基礎邏輯服務。業務邏輯服務封裝了業務邏輯,是後台提供給微信客戶端調用的API。基礎邏輯服務則抽象了更底層和通用的業務邏輯,提供給業務邏輯服務訪問

存儲層包括數據訪問服務和數據存儲服務。數據存儲服務通過MySQL和SDB(廣硏早期後台中廣泛使用的Key-Table數據存儲系統)等底層存儲系統來持久化用戶數據。數據訪問服務適配並路由數據訪問請求到不同的底層數據存儲服務,面向邏輯層提供結構化的數據服務

3. 微信技術總監談架構:微信之道——大道至簡(演講全文)

微信——騰訊戰略級產品,創造移動互聯網增速記錄,10個月5000萬手機用戶,433天之內完成用戶數從零到一億的增長過程,千萬級用戶同時在線,搖一搖每天次數過億...在技術架構上,微信是如何做到的?日前,在騰訊大講堂在中山大學校園宣講活動上,騰訊廣研助理總經理、微信技術總監周顥在兩小時的演講中揭開了微信背後的秘密。

周顥把微信的成功歸結於騰訊式的「三位一體」策略:即產品精準、項目敏捷、技術支撐。微信的成功是在三個方面的結合比較好,能夠超出絕大多數同行或對手,使得微信走到比較前的位置。所謂產品精準,通俗的講就是在恰當的時機做了恰當的事,推出了重量級功能,在合適的時間以最符合大家需求的方式推出去。他認為在整個微信的成功中,產品精準佔了很大一部分權重。

相關鏈接

周顥

2001 年畢業於華南理工大學,計算機專業碩士。

2005 年加入騰訊廣州研發部,歷任 QQ 郵箱架構師,

廣研技術總監,T4 技術專家,微信中心助理總經理。

微信研發團隊里鼓勵一種試錯的信仰:他們堅信,在互聯網開發里,如果能夠有一個團隊在更短的時間內嘗試了更多機會(並能改進過來),就能有(更多的)機會勝出。敏捷是一種態度,在軟體開發過程中,項目管理者都會非常忌諱「變更」這個詞,但是在微信的項目運作中是不可以的。因為微信必須要容忍說哪怕在發布前的十分鍾,也要允許他變更。這是非常大的挑戰,因為打破了所有傳統項目開發的常識。所有人都說不可能做到的,但微信做到了。研發團隊所做的一切都是要給產品決策者有最大的自由度,而這個決策正是微信能夠勝出的關鍵。

敏捷有很多困境,如果做一個單機版程序,是可以做到很敏捷的,但是騰訊正在運作的是一個海量系統,有千萬級用戶同時在線,在一個單獨的功能上每天有百億級的訪問,同時還要保證99.95%的可用性。在海量系統上應對項目開發會有很嚴謹的規范,都說要盡可能少的變化,因為90%-95%的錯誤都是在變更中產生的,如果系統一直不變更會獲得非常高的穩定度,但是微信就是要在懸崖邊跳舞。微信的研發團隊要做一些事情,讓敏捷開發變得更簡單。

如何做到這一切?周顥認為,首先,必須建立起一種狂熱的技術信念,就是一定是可以做到的。然後,需要用一些穩固的技術(理念)來支撐,例如大系統小做、讓一切可擴展、必須有基礎組件、輕松上線(灰度、灰度、再灰度;精細監控;迅速響應)...等等來支撐。

當設計龐大系統的時候,應該盡量分割成更小的顆粒,使得項目之間的影響是最小的。僅僅把模塊變得更為清晰,這在海量系統設計開發中是不夠的,還需要在物理環境上進行分離部署,出現問題的時候可以快速發現,並且在最快的情況下解決掉。

大系統小做,混搭模式:

將不同的應用邏輯物理分割獨立出來,用戶注冊登錄、LBS邏輯、搖一搖邏輯、漂流瓶邏輯、消息邏輯獨立開來。把關鍵的邏輯混搭在一起,當所有的邏輯部署在同一個伺服器上,確實也會帶來很大敏捷上的好處,因為不需要額外的考慮部署和監控的問題。在整個微信的邏輯中,可能現在已經有上百種不同的邏輯,因為會在邏輯的分割上拆分成8-10種做分離部署。

在高穩定度、高性能的系統中間,為了穩定性能把它設計成不變化的系統,但為了支持敏捷需要讓一切的東西都要變得可以擴展。

擴展的關鍵點有兩塊。一個是網路協議需要擴展,當要升級一個新功能的時候,會有一些比較大的困難,所以所有協議設計都比較向前兼容,但是向前兼容還是不夠的,因為網路協議設計本身有非常多的功能也會有比較大的欄位,相關的代碼可能會有數千行,這一塊不能通過手寫方式完成。可以通過XML描述,再通過工具自動生成所有的代碼,這是微信獲得快速開發的一個重要的點。

另外一塊就是在數據存儲方面是必須可擴展的。在2005年絕大多數海量系統的設計都是採用固定欄位的存儲,但是在現代系統中會意識到這個問題,會採用KV或者TLV的方式,微信也做了不同的設計。

把復雜邏輯都固化下來,成為基礎軟體。在微信後台會有幾種不同的基礎組件。大致包括:

在變更後的部署方式上,微信在一些規則會限定不能一次把所有的邏輯變更上去,每一次變更一小點觀察到每一個環節沒有問題的時候,才能布局到全網上去。微信後台每一天可以支撐超過20個後台變更,在業界來說,通常做到5個已經是比較快了,但是微信可以做到快4倍。

騰訊內部的上線系統:

而所謂灰度發布,是指在黑與白之間,能夠平滑過渡的一種發布方式。AB test就是一種灰度發布方式,讓一部用戶繼續用A,一部分用戶開始用B,如果用戶對B沒有什麼反對意見,那麼逐步擴大范圍,把所有用戶都遷移到B上面 來。灰度發布可以保證整體系統的穩定,在初始灰度的時候就可以發現、調整問題,以保證其影響度。(在騰訊,灰度發布是最常採用的發布方式之一)

常識上,解決一個復雜問題的時候,會用高明的技巧解決復雜的問題,這個不是微信團隊的目標,他們追求的要做到讓所有問題很自然和簡單的方式解決掉。在周顥看來,微信架構的技術復雜點在四個要點:協議、容災、輕重、監控。

微信架構:

在協議設計上,移動互聯網和常規互聯網有很大的區別。首先有CMWAP和CMNET的不同,在中國現在有相當多的手機用戶使用WMWAP連接,還有就是在線和離線的概念,當QQ下線的時候叫離線,當你登錄的時候叫在線。但是在移動互聯網這兩個概念比較模糊。從微信的設計中,不管在線還是離線系統表現都應該是一致的。還有一個是連接不穩定的問題,由於手機信號強弱的變化,當時信號很好,5秒鍾走到信號不好的地區,連接就必須斷掉。這個中間帶來不穩定的因素為協議設計帶來較大困難。此外就是資費敏感的問題,因為移動互聯網是按照流量計費的,這個計費會使得在協議設計中如何最小化傳輸的問題。最後就是高延遲的問題。

對此,業界標準的解決方案:Messaging And Presence Protocol:1)XMPP;2)SIP/SIMPLE。它的優點是簡單,大量開源實現。而缺點同樣明顯:1)流量大:狀態初始化;2)消息不可靠。

微信在系統中做了特殊設計,叫SYNC協議,是參考Activesyec來實現的。特點首先是基於狀態同步的協議,假定說收發消息本身是狀態同步的過程,假定終端和伺服器狀態已經被遲了,在伺服器端收到最新的消息,當客戶端、終端向伺服器對接的時候,收取消息的過程實際上可以簡單的歸納為狀態同步的過程,收消息以及收取你好友狀態更新都是相同的。在這樣的模式之下,我們會也許會把交互的模式統一化,只需要推送一個消息到達的通知就可以了,終端收到這個通知就來做消息的同步。在這樣的簡化模式之下,安卓和塞班都可以得到統一。這樣的系統本身的實現是更為復雜的,但是獲得很多額外的好處。

讓剩下系統實現的部分更加簡單,簡化了交互模式,狀態同步可以通過狀態同步的差值獲得最小的數據變更,通過增量的傳輸得到最小的數據傳輸量。通過這樣的協議設計,微信可以確保消息是穩定到達的,而且是按序到達。引用一句俗話:比它炫的沒它簡單,比它簡單的沒它快,沒誰比他更快,哪怕在GPRS下,微信也能把進度條輕易推到底。

周顥介紹了在微信上具體容災設計的做法。在所有的容災中存儲層的容災是最難的,一個系統的設計分為三層:接入層、邏輯層、存儲層。接入層和邏輯層的容災都有比較成熟的方案。邏輯層的容災相對來說比較簡單,盡量不要有狀態的設計,比如說當你做上一個請求的時候,會保持一些狀態,要使得下一個請求發到下一個伺服器。如果任何一個請求之間互相不關聯的話,這個就是無狀態的設計,只要做到這一點邏輯層的容災可以隨意的切換。在回到存儲層本身的容災設計上,相對來說困難一些,但是微信研發團隊採用了一些技巧,叫分而治之,分離業務場景,尋求簡單的設計,並不會尋求大而同一的解決方案,因為這樣會使得系統的復雜度大幅度上升,而微信會盡可能把產品拆細,尋求簡化的設計。

首先是主備容災,這是最常見的方案。在有一些業務場景中是可以容忍最終一致性的,比如賬號系統的設計,每天寫入賬號系統的請求是非常少的,但是訪問的請求非常多,這個差異可能會達到數萬倍的規模,在這樣的場景下,微信會在賬號系統中採用簡化的方案,也可以獲得比較大的穩定度。

SET模型+雙寫:

第二種容災的模式叫雙寫,兩台Master的機器,當一台機故障的時候,另外一台機還是可以接收到寫請求,當兩台機交錯啟動的時候,會得到數據的丟失。但是有一些場景是可以容忍輕度數據丟失的,比如說會有一個存儲專門記錄用戶終端的類型,比如說安卓還是塞班以及他們使用終端的微信版本是什麼,這樣的數據是可以容忍輕度數據丟失的,因為偶爾有一些丟失的話,下一次訪問會把這些數據帶上來,會盡快的修復所有的數據。雙寫也是非常簡單的模式。

微信的研發團隊做了一個叫Simple Quorum的機制,在微信的後台中,同步協議有一個很重要的基石叫序列發生器,這樣的一個序列發生器需要有極高的穩定度。首先可以看到序列號有一個特點永遠是遞增的,用遞增方式往前推進的時候,最大的序列號就是最新的系列號。有一個畢業才加入廣研的畢業生想到一個絕佳的方案,按SET分布,從2G減到200K。

周顥還談到了輕重的概念。這個概念的提出主要是從終端本身的一些困境所帶來的。首先在終端上需要表現最多的一個產品的邏輯,邏輯非常復雜,變更的成本也非常高,當需要修復的時候必須發布一個新版本,這個新版必須由自己下載才能完成,下載的成本非常高。在這樣的前提下,如果手機終端產生了任何變化的時候,如果這個變化有非常大的問題就會有極大的困境,所以需要在每一個發布之前做一些充分的數據,確保不會發生致命問題。如果一旦出現致命問題難以修復,需要把關鍵的點從終端移到後台實現,把功能點後移,來充分發揮後台快速變更的能力。

接入優化:從GSLB到IP重定向

在接入層的優化,速度很重要的因素,是不是能夠就近接入一個最優的節點,比如說移動用戶最好接入移動的節點,海外的用戶可能需要尋找更佳的路由,有的時候可能無法自動做到這一點,一點是在終端上做測速,微信會通過在後台IP逆向的能力,通過後台指揮微信終端聯網的能力,尋找最優的接入點。上圖就是每分鍾收到同一項指令曲線的報表。

如何解決「偷流量」的問題 ——當國內類微信類產品發布的時候出現一個大的問題就是「偷流量」,當用戶在某一些邏輯下進行一個死循環,不斷訪問某一些數據,這樣的死循環是非常可怕的,如果在用戶不知覺的情況之下,可能會在一個小時之內偷到數10兆甚至數百兆的流量。有非常多業內的同行都需要花大量的精力解決這個問題,微信研發團隊用了非常強大的方式解決它。通過在後台建立起嚴厲的監控系統,對每一個用戶的行為做一個監控,當發現異常的時候,後台會給終端發出指令,使得微信終端在一段時間無法聯網,但是可以保證用戶流量不會白白的使用掉。

功能適配的例子 ——第一期微信版本發布的時候,當時沒有群聊的功能,第二版發布的時候做了這個功能。當時有兩個選擇,對於早期版本的用戶,因為不支持群聊,就無法享用到這個功能,但是微信希望提供更好的選擇,想讓早期不支持群聊的版本,也可以被拉到一個群裡面收消息、發消息,通過後台功能的適配也能做到這個事情。

對於一個海量系統來說,一個精密的儀表盤非常重要。監控是非常痛苦的,對於這樣一個系統來說,每小時會產生數百G的監控日誌。微信希望在1分鍾之內監控的數據就能夠顯示在報表上,因為只有這樣的精準和實時度才能夠贏得處理故障的時間。微信會做關聯統計,通過搖一搖加了好友,他們活躍度如何,過了一段時間他們的活躍度變化情況又是如何。這種需求是需要通過大量日誌的關聯統計來獲得的。研發團隊也花了一段時間來理解這個問題,發現了中間一個重要的經驗叫做「魚和熊掌不能兼得」。

為了讓監控數值更敏感,需要把監控細化再細化,上面數據表示每一欄子系統的數據,下面這個是按微信版本號來劃分的,這里的數據項是非常多。

微信還需要採集一些異常的點,如果有異常的話會發布緊急的版本,盡可能快的替換它。對收發消息延時做的監控,比如說0—1秒端到端的速度,會對不同的區段做一些統計,當某一個環節出現異常的時候,通常會在中間的延時上體現出來。有一個很重要的點叫自動報警,現在有數千項的數據,不可能每一項都靠人工去看的,必須要跟自動報警相關聯,微信有一些智能的演算法,是不是在正常的范圍內,跟 歷史 的數值進行對比,如果有異常的話,會通過簡訊、郵件還有微信本身來發出報警信息。

微信會把監控嵌入到基礎框架裡面去,因為並不是每一個人都會意識到在需要的地方嵌入一個監控點,所以在基礎框架本身內置很重要的監控點,比如說這個表上的欄目,非常多的欄目大概會有數百項的欄目,都不需要程序員自己去寫,當用基礎組件搭建一個系統的時候,就可以直接觀測系統數據。

在談到微信未來的技術挑戰時,周顥首先希望能夠讓微信成為可用性99.99%的系統;設計出面向現在10倍容量的系統以及完全的IDC容災。

網上盛傳的凌晨兩點,騰訊大廈那多層大片大片的燈光和樓下那長長的計程車隊伍說明了一切。引用一句話做結尾:「可怕的不是微信,真正可怕的是,比你領先比你更有天賦的團隊比你更努力」。

4. 微信後台如何做的過載保護

首先要談到架構,微信後台系統的模型大致理解為三層架構,接入層(proxy)、邏輯層(CGI)、存儲層(後台模塊)。啥意思呢?由接入層mmproxy調用邏輯層的CGI,比如搖一搖或者發消息的CGI,邏輯層再和存儲層通信,比如存取賬戶信息,文件,地址信息等等。這是常規主流的架構沒有什麼特別需要說明的了,這邊採用的是微服務架構,通信使用RPC框架,調用下級模塊過多,就有 高扇出 問題。

我們先來理一下過載可能導致的一些現象。假設後台模塊系統極限請求量是60萬,我們知道當實際請求量超過這個數值就會過載,那麼過載會發生什麼情況?是不是發送了70萬請求過來,只有60萬之外的那10萬請求不能被處理?答案顯然不是,實際情況要比這個糟很多。很顯然系統一旦過載,可能就只能正常處理20萬的請求,原來的60萬極限值處理能力是保不住的,甚至還有可能雪崩,直至毫無處理能力。當然,這裡面的原因有很多,比如無效響應,失敗重試,級聯傳遞等等。

假如一時間好多人發送了搖一搖請求,這些請求都依次入隊准備去調用尋找同搖好友的CGI並等待響應結果。但是隊列很長,假設這些請求的超時時間是5秒,等待時間如果6秒過長就會導致RPC超時,一旦超時調用方可能直接關閉不再等待響應,等隊列排到後執行完邏輯返回的響應調用方此時並不接收也等於是屬於無效的響應了。來舉個栗子,春運快到了,你擠在車站排隊買車票,假設最後一班發車只有60分鍾了,窩了個大叉,當你排隊了半天到達售票窗口時已經用時80分鍾了,這時候售票員再給你吐出一張車票已經毫無意義了,車都跑了。這也叫「無效輸出」。

當然除了大部分無效的響應處理耗走了資源,別忘了還有失敗重試。一般RPC框架都會設置失敗重試機制,當請求得不到響應調用端會重試,如果一時間失敗過多將會導致短時間內大量重試請求的發起,導致進一步過載,無疑是對本已經並無富裕的系統負載雪上加霜,滾雪球效應。

由於採用微服務架構,各模塊之間的調用相互影響。由於服務依賴的復雜性當前模塊的雪崩會導致上游模塊的變慢,性能下降,如果此時上游模塊也開始過載,繼續向上級聯,從而導致整個系統崩潰。怎麼理解呢?假設一個餐廳里的2個廚師,A桌定了2個大菜烹飪時間很長,那麼就會影響傳菜員的上菜速度,傳菜員要等待,假設全店傳菜員有限只有2個都在等廚師出A桌的2個菜後才能去服務其他桌,這個時候就影響了整個餐廳的顧客的用餐速度,最終可能導致好幾桌的顧客都吃不上菜且罵罵咧咧跑了。其實這個在Hystrix里採用了資源隔離來解決這個問題,即一個傳菜員只服務於一桌,A服務員只服務A桌,B服務B桌,A慢的話就A這一桌慢,B桌的傳菜員只傳他B桌的菜哪怕閑著玩手機也不理其他桌。

談完原因談解決方法。該怎麼處理呢?其實Hystrix的這套思想很好了,基本思想核心也相似,但今天主要是談微信後台實踐的解決方案。

常見的過載保護方法

1.減少需求:調用端的請求限速

2.避免響應超時:根據調用端超時,設置T超時時間;控制隊列長度,容納T超時時間內的請求。

調用端限速

限多了,伺服器能力沒有充分利用,限少了,過載問題沒解決。而且過載時,響應時間會階梯式上漲,這樣超時時間就會 波動 ,隊列長度難設定。雖然極限能力 絕對值 比較難找,但伺服器最佳負載點容易找。所以過載保護的目標:盡量讓服務端維持在最佳負載點, 讓有效輸出接近最佳吞吐 。

古希臘水鍾

那如何維持在最佳負載點呢?水鍾的啟示:反饋控制系統。

如圖,圖中的浮子上浮,上水箱下水減速,相反如果下沉則加速上水箱下水。浮子起到了穩定液位的作用,使得中水箱的水位相對穩定,往下水箱的滴水速率自然也相對穩定,使得計時相對准確。

那麼OK啦,也就搞一個像浮子一樣的機制,多了及早拒絕,降低通過率,少了緩慢提升通過率。

1、通過反饋動態調整通過率:及早拒絕

根據CPU使用率和隊列等待時間,控制輸入,這里有個演算法FastReject V1計算的是 通過率 ( 過載時 按一定概率通過請求),演算法公式暫不展示,主要講究的是快降慢升。觸發降低通過率的場景比如有:比如每隔一秒統計一下隊列等待時間,超過n豪秒就降低通過率,或者當前CPU使用率超過閾值(比如85%)也降低通過率。及時反饋控制,不讓隊列等很久等到輪到自己被處理後前端已經關閉了請求,導致無效的響應。這樣請求要麼超載被直接拒絕,要麼是有效響應,保持原來的處理能力,不讓過載雪崩。這就是出隊時再判斷超時還是入隊時就判斷的區別。記得這個在Hystrix限流熔斷里叫做「降級返回」。

2、同時計算業務的優先順序權重:優先服務重要業務

這有點類似早高峰的公交專用道了,由公交車優先通行。實現其實也比較簡單,為每個業務(CGI)指定一個優先順序(這個優先順序可以由後台根據業務實際配置),每個請求帶個是屬於什麼業務的標識,FastReject對每個業務優先順序維持一個通過率,低優先順序通過率降為0,開始拒絕更高優先順序。比如聊天消息發送的優先順序為1,上傳文件為2,數字越小優先順序越高。當上傳文件的通過率降為0後開始降聊天消息的通過率,這樣保證了優先服務重要業務。這個在Hystrix里類似服務的「優雅降級」。

這里的優先順序信息傳遞用的是RPC COOKIE。因為RPC框架支持cookie,那就剛好借用類似http cookie 的思想,請求/響應包預留cookie 欄位,請求攜帶cookie跨模塊自動傳遞。比如CGI_ID標識或者下面分組提到的用戶ID。

3、用戶分組:保證要不過第一次就不過

注意了,這里的內容大家可能會比較感興趣。這里要從剛剛上面的那個優先順序說起。我們知道,微服務架構各模塊之間的調用相互影響,如果一個請求服務端需要請求多個模塊才能處理完邏輯返回結果。那假如說請求R需要經過A模塊請求B模塊,B模塊再請求C,B再請求D等等(注意這里B需要同時請求C、D兩個模塊獲取結果),那麼如果請求通過了A模塊的通過率,C模塊的通過率,到D模塊沒通過,那麼前面的處理是不是都白費了,又違背了我們之前所做的及時拒絕無效響應的原則。那怎麼解決呢?這里採用了用戶分組的方式。舉個例子,比如現在根據QQ號對用戶進行分組,從0-9取尾號散列分為10組。QQ號為123的請求過來,首先用戶是被分到3組的,如果在C模塊被拒絕,那麼該用戶乃至該組的其他用戶直接在D模塊或者後續E,F等模塊的調用都會被全部拒絕,這就是按組拒絕。保證一個用戶要不過第一次請求就不過,不會說在聊天聊一半發不了消息了或者消息在中途某個服務才開始失敗。 用戶分組思想類似單雙號限行。

這里有個有趣的事情,比如某用戶被分到3組,3組被拒,那麼他是不是每次過來都是被拒的,這要是搶紅包那你不是會直呼「不公平」。所以這里做個小調整,如果這里每隔一段時間變換散列演算法,前一分鍾123可能是3組,後面可能是7組,這樣來解決同一個用戶每次來都被拒的情況,而其他用戶都不會被拒的情況,也算是公平了。

4、讓調用端也帶FastReject接收服務端反饋:服務不行調用端就直接不發起請求了

這一點也很好理解,RPC將每次返回信息也反饋給調用端,調用端在調RPC前先自我檢查,看看服務是不是已經不行了,如果不行了就乾脆直接不發起請求過來了,避免請求過多。這一點有點類似Hystrix的熔斷器機制,接收反饋並自動作熔斷操作,服務降級。

總結:實際上,這和Hystrix思想其實大同小異,可以看下 《通俗一點講「限流熔斷之Hystrix」》 就會發現太多的異曲同工之妙。就到這里,說好的淺談輒止的,感謝品閱~~。

恭祝大家新年快樂!萬事大吉!

相關文獻:

《Overload control for scaling WeChat microservices》

《10億紅包從天而降,揭秘微信搖一搖背後的技術細節》

5. 微信公眾號的運營大數據分析

微信公眾號的運營大數據分析

微信運營,到底是什麼鬼東西?周末約了幾個朋友聊天,大家討論微信怎麼做,目前大部分都處於迷茫狀態,策劃好的話題,設計、編輯、發布,然後沒人看,然後堅持了大半個月,然後仰天長嘆:「滾犢子,微信」。

經過大半年的研究,總結了一些後台數據,給大家分析一下,如何有效利用微信後台數據,有預謀有組織的做微信運營。

第一部分:用戶增長來源分析

從上圖可以明顯的看出,微信用戶的增長主要來源於「搜索公眾號」和其他,我們先搞清楚這些指標的具體含義。

搜索微信公眾號的名稱:指通過搜索微信公眾號的名稱獲得關注,比如搜索「人和網」這個名字,在搜索的時候,一直排在第一名,進行外部推廣的時候,用戶很容易通過搜索找到你。所以取個簡單有聯想的名字更容易讓用戶記住,認證比非認證更容易獲得用戶關注。

其他:大部分賬號的粉絲來源,都是「其他」類最多,很多人搞不明白其他是什麼,一般包括3個渠道,

1、圖文消息標題下藍色鏈接。

圖文標題下藍色鏈接

2、微信公眾號二維碼:微信可以長按識別二維碼大大促使了這個渠道的用戶來源,可惜的是目前只有微信可以做到。

3、廣點通系統推廣:付費推廣的一種,據說目前加粉的成本1.2左右,比活動的性價比要高了。

搜索微信號,因此微信號要足夠簡潔容易讓用戶記住,在外部推廣的時候用戶方便搜索。一般搜索微信ID的佔比不是很高,大概也就8%左右,這是一個很奇怪的數據,大部分做推廣的時候留下的是微信號,但是用戶來源的時候更多是通過公眾號名稱搜索,可以看出,其實用戶對於資訊網站或者社區看到的企業推廣信息更多選擇公眾號名稱搜索而不是微信號搜索。

圖文消息右上角菜單,這個關注按鈕隱藏較深,很多人不知道閱讀文章時的右上角按鈕里還隱藏了這么多功能,而且需要經過2步才能到公眾號介紹頁,最坑爹的是這個按鈕不是在所有閱讀的情況下都會出現,所以後台通過這個關注的幾乎為零,也不知道哪些用戶習慣這種操作。

名片分享,直接的名片分享,一般是用戶通過分享給好友或者朋友圈微群,這個數據佔比越高,說明這個號的質量越好,大家願意主動分享傳播。

第二部分:圖文閱讀分析

圖文閱讀分析主要包含7個指標:圖文頁閱讀人數、圖文頁閱讀次數、原文頁閱讀人數、原文頁閱讀次數、分享轉發人數、分享轉發次數、微信收藏人數;

分析數據首先需要了解這些指標的含義:

圖文頁閱讀人數:指你發的那條圖文消息,有多少人看過。

原文頁閱讀人數:指的是你添加的原文鏈接有多少人看過。如果沒有加,那麼原文頁閱讀人數就顯示為0,更多用於活動的鏈接宣傳,根據統計,一般文章的原文鏈接點擊率非常低。

這里重點看下圖文頁閱讀人數來源,微信後台提供了5個來源渠道:會話、好友轉發、朋友圈、騰訊微博、歷史消息。

會話:指通過你推送的消息(會話窗口)查看到你的內容,復制鏈接發送給好友等等。

好友轉發:通過轉發直接分享給好友,多見於好文,干貨,同行之間或者好友之間樂意分享。

朋友圈:這個不用說了,大家都非常熟悉。

騰訊微博:用騰訊微博的不多,所以這個渠道來源少之又少。

歷史消息:微信閱讀歷史文章率不是很高,一般用戶更多通過收藏去閱讀你的歷史文章。

其他:以上四種以外的都是其他,具體怎麼來的,其實我也不清楚,反正數據不是很大, 所以參考意義也不是很大。

以人和網公眾號一篇10萬+閱讀文章為例,看下用戶的閱讀來源:

文章閱讀量主要來源於用戶分享後的朋友圈,標題影響用戶打開率,但是無法保證足夠多的閱讀量,轉發才是閱讀增長的核心。所以,微信的運營最終還是回到內容的價值。

做好內容,拓展分享渠道,才是獲得用戶的重點之策。

第三部分:用戶屬性分析

微信後台提供了性別、語言、省份、城市、終端、機型。這部分根據你針對的用戶不同主要起到參考作用,也就是你的推廣所獲得粉絲是否是你的想要的。

以人和網為例:

從前十的佔比情況看,顯然符合人和網的人群定位,主要分布與江浙滬北上廣,占總用戶分布的57.2%.

還有用戶機型、性別數據,針對不同的微信做針對性的分析,不同微信的定位人群不一樣,在推廣以及活動中,需要有效的送達到目標用戶,這部分數據就能夠提供很多幫助。

第四部分:10萬+文章案例分析

10萬+閱讀文章6月1日的當天各個時間段轉發次數和閱讀人數,很明顯的看出,在晚上20點到24點,用戶分享和閱讀是直線上升的,也說明這個時間段閱讀微信的人數是最多的。

這個表格是具體的時間段轉發和閱讀人數,我們重點關注下轉發閱讀比,這個數據的好處在於避開因為累積分享造成閱讀量過高造成的數據誤差。表格中凌晨1點到2點的時候比例較高,說明這個時間段分享的人雖然少,但是朋友圈閱讀率比較高,大部分人已經關機入睡,部分夜貓子還在刷屏看微信,很少的分享可以獲得更高用戶到達率。這個數據佔比比較高的在中午、晚上,尤其是19點以後,都保持在10%以上,這個時間段用戶有更多的時間支配刷微信,也是很多公眾號推送文章的高峰期。

現實中,很多微信運營者只是一份工作的訴求,所以大部分選擇在臨近下班的時候推送圖文消息,一方面下班了可以及時回家,一方面感覺下班路上看微信的人比較多,其實這是一種錯誤的想當然,很多人開車、擠地鐵擠公交其實看手機的並不一定就是最多的時間段。所以建議微信運營在晚上20點-22點推送比較好,有些人可能覺得不方便,晚上回家還要開電腦推送文章,其實微信已經有手機端服務了,關注微信公眾號助手,就可以通過手機推送了。一般我推送文章時間都在晚上20點左右,或者晚些。

第五部分:10萬+文章後台數據

大概一周時間閱讀量分布數據

最終閱讀量

至於這篇文章怎麼操作的,可以查看下人和網以前的文章,有分享過,而且粉絲數量很少的情況下做到的10萬+閱讀。

第六部分:自媒體推廣方式

這是其中一次的推廣文章詳細列表,這樣做的好處有:

1、文末可以做公眾號的推廣。根據上文分析來看,留下公眾號名稱比微信號效果更好,不同平台的管理辦法不一樣,這個要根據實際情況具體對待。

2、可以積累一些媒體資源,跟媒體網站編輯搞好關系,可以不斷的擴增你的媒體圈和在行業中的影響力。

3、很多微信運營每天在找優質的素材,如果你能提供比較好的文章,他們也會轉載。由於我做的公眾號已經被邀請原創。所以轉載的公眾號排版推廣信息都無法修改,有著很好的傳播效果。不過根據最近的數據來看,加粉效果不是很好。

部分文章被轉載的情況,有些大號進行了轉發, 閱讀量也都還不錯,不過對加粉來說效果不是很理想,這部分的用戶增長來源渠道為「其他」。

轉發公眾號的顯示效果, 點擊人和網會直接跳轉到人和網公眾號,不過似乎這個點擊數據效果不是很好,所以騰訊即使做了原創保護功能,但是轉載的對於原公眾號產生的效果有限,最多是他們知道「人和網」,至於到底是什麼東西,還是不知道。或者感興趣的用戶會通過文章最下方的二維碼掃描關注,一個大號幫你轉發了原創文章,其實對於一個小號來說,還是非常實惠的,所以運營者一定要在內容上下工夫才是王道。

好的內容一定要通過媒體傳播出去,尤其是一些垂直權威性的網站,畢竟很多運營者都是通過這些網站尋找優質的素材,前期公眾號的傳播有限,其他運營者不可能發現你的優質內容,通過外部權威網站就是最好的方法。

當然這個前提是你的文章是原創,這樣別人轉載對你才有幫助,否則都白談。

運營微信號一定要找到方法,總結做過的好的方法的經驗,通過數據分析來優化推廣方式。

以上是小編為大家分享的關於微信公眾號的運營大數據分析的相關內容,更多信息可以關注環球青藤分享更多干貨

6. 微信朋友圈的基本數據結構設計是怎麼樣的

因為規則很簡單:任何信息只有發布者本人的好友可見(准確的說是有朋友圈許可權的賬號可見)。誰發布 ,誰的好友可見 ,無論信息是 話題主體或話題下的評論。
所以,解決方案也應該比較簡單。
比如:背後的表可以是 :
表1:以好友關系為管理對象的表,key為用戶賬號:userid,好友01id,。。。。。。。。
表2:以發布內容為管理對象的表,key為用戶賬號:userid,發布內容編號,發布時間,具體內容數

7. 【OpenIM轉載】萬億級調用系統:微信序列號生成器架構設計及演變

微信在立項之初,就已確立了利用數據版本號實現終端與後台的數據增量同步機制,確保發消息時消息可靠送達對方手機,避免了大量潛在的家庭糾紛。時至今日,微信已經走過第五個年頭,這套同步機制仍然在消息收發、朋友圈通知、好友數據更新等需要數據同步的地方發揮著核心的作用。

而在這同步機制的背後,需要一個高可用、高可靠的序列號生成器來產生同步數據用的版本號。這個序列號生成器我們稱之為seqsvr,目前已經發展為一個每天萬億級調用的重量級系統,其中每次申請序列號平時調用耗時1ms,99.9%的調用耗時小於3ms,服務部署於數百台4核CPU伺服器上。 本文會重點介紹seqsvr的架構核心思想,以及seqsvr隨著業務量快速上漲所做的架構演變。

微信伺服器端為每一份需要與客戶端同步的數據(例如消息)都會賦予一個唯一的、遞增的序列號(後文稱為sequence),作為這份數據的版本號。 在客戶端與伺服器端同步的時候,客戶端會帶上已經同步下去數據的最大版本號,後台會根據客戶端最大版本號與伺服器端的最大版本號,計算出需要同步的增量數據,返回給客戶端。這樣不僅保證了客戶端與伺服器端的數據同步的可靠性,同時也大幅減少了同步時的冗餘數據。

這里不用樂觀鎖機制來生成版本號,而是使用了一個獨立的seqsvr來處理序列號操作,一方面因為業務有大量的sequence查詢需求——查詢已經分配出去的最後一個sequence,而基於seqsvr的查詢操作可以做到非常輕量級,避免對存儲層的大量IO查詢操作;另一方面微信用戶的不同種類的數據存在不同的Key-Value系統中,使用統一的序列號有助於避免重復開發,同時業務邏輯可以很方便地判斷一個用戶的各類數據是否有更新。

從seqsvr申請的、用作數據版本號的sequence,具有兩種基本的性質:

舉個例子,小明當前申請的sequence為100,那麼他下一次申請的sequence,可能為101,也可能是110,總之一定大於之前申請的100。而小紅呢,她的sequence與小明的sequence是獨立開的,假如她當前申請到的sequence為50,然後期間不管小明申請多少次sequence怎麼折騰,都不會影響到她下一次申請到的值(很可能是51)。

這里用了每個用戶獨立的64位sequence的體系,而不是用一個全局的64位(或更高位)sequence,很大原因是全局唯一的sequence會有非常嚴重的申請互斥問題,不容易去實現一個高性能高可靠的架構。對微信業務來說,每個用戶獨立的64位sequence空間已經滿足業務要求。

目前sequence用在終端與後台的數據同步外,同時也廣泛用於微信後台邏輯層的基礎數據一致性cache中,大幅減少邏輯層對存儲層的訪問。雖然一個用於終端——後台數據同步,一個用於後台cache的一致性保證,場景大不相同。

但我們仔細分析就會發現,兩個場景都是利用sequence可靠遞增的性質來實現數據的一致性保證,這就要求我們的seqsvr保證分配出去的sequence是穩定遞增的,一旦出現回退必然導致各種數據錯亂、消息消失;另外,這兩個場景都非常普遍,我們在使用微信的時候會不知不覺地對應到這兩個場景:小明給小紅發消息、小紅拉黑小明、小明發一條失戀狀態的朋友圈,一次簡單的分手背後可能申請了無數次sequence。

微信目前擁有數億的活躍用戶,每時每刻都會有海量sequence申請,這對seqsvr的設計也是個極大的挑戰。那麼,既要sequence可靠遞增,又要能頂住海量的訪問,要如何設計seqsvr的架構?我們先從seqsvr的架構原型說起。

不考慮seqsvr的具體架構的話,它應該是一個巨大的64位數組,而我們每一個微信用戶,都在這個大數組里獨佔一格8bytes的空間,這個格子就放著用戶已經分配出去的最後一個sequence:cur_seq。每個用戶來申請sequence的時候,只需要將用戶的cur_seq+=1,保存回數組,並返回給用戶。

預分配中間層

任何一件看起來很簡單的事,在海量的訪問量下都會變得不簡單。前文提到,seqsvr需要保證分配出去的sequence遞增(數據可靠),還需要滿足海量的訪問量(每天接近萬億級別的訪問)。滿足數據可靠的話,我們很容易想到把數據持久化到硬碟,但是按照目前每秒千萬級的訪問量(~10^7 QPS),基本沒有任何硬碟系統能扛住。

後台架構設計很多時候是一門關於權衡的哲學,針對不同的場景去考慮能不能降低某方面的要求,以換取其它方面的提升。仔細考慮我們的需求,我們只要求遞增,並沒有要求連續,也就是說出現一大段跳躍是允許的(例如分配出的sequence序列:1,2,3,10,100,101)。於是我們實現了一個簡單優雅的策略:

請求帶來的硬碟IO問題解決了,可以支持服務平穩運行,但該模型還是存在一個問題:重啟時要讀取大量的max_seq數據載入到內存中。

我們可以簡單計算下,以目前uid(用戶唯一ID)上限2^32個、一個max_seq 8bytes的空間,數據大小一共為32GB,從硬碟載入需要不少時間。另一方面,出於數據可靠性的考慮,必然需要一個可靠存儲系統來保存max_seq數據,重啟時通過網路從該可靠存儲系統載入數據。如果max_seq數據過大的話,會導致重啟時在數據傳輸花費大量時間,造成一段時間不可服務。

為了解決這個問題,我們引入號段Section的概念,uid相鄰的一段用戶屬於一個號段,而同個號段內的用戶共享一個max_seq,這樣大幅減少了max_seq數據的大小,同時也降低了IO次數。

目前seqsvr一個Section包含10萬個uid,max_seq數據只有300+KB,為我們實現從可靠存儲系統讀取max_seq數據重啟打下基礎。

工程實現

工程實現在上面兩個策略上做了一些調整,主要是出於數據可靠性及災難隔離考慮

接下來我們會介紹seqsvr的容災架構。我們知道,後台系統絕大部分情況下並沒有一種唯一的、完美的解決方案,同樣的需求在不同的環境背景下甚至有可能演化出兩種截然不同的架構。既然架構是多變的,那純粹講架構的意義並不是特別大,期間也會講下seqsvr容災設計時的一些思考和權衡,希望對大家有所幫助。

seqsvr的容災模型在五年中進行過一次比較大的重構,提升了可用性、機器利用率等方面。其中不管是重構前還是重構後的架構,seqsvr一直遵循著兩條架構設計原則:

這兩點都是基於seqsvr可靠性考慮的,畢竟seqsvr是一個與整個微信服務端正常運行息息相關的模塊。按照我們對這個世界的認識,系統的復雜度往往是跟可靠性成反比的,想得到一個可靠的系統一個關鍵點就是要把它做簡單。相信大家身邊都有一些這樣的例子,設計方案里有很多高大上、復雜的東西,同時也總能看到他們在默默地填一些高大上的坑。當然簡單的系統不意味著粗製濫造,我們要做的是理出最核心的點,然後在滿足這些核心點的基礎上,針對性地提出一個足夠簡單的解決方案。

那麼,seqsvr最核心的點是什麼呢?每個uid的sequence申請要遞增不回退。這里我們發現,如果seqsvr滿足這么一個約束:任意時刻任意uid有且僅有一台AllocSvr提供服務,就可以比較容易地實現sequence遞增不回退的要求。

但也由於這個約束,多台AllocSvr同時服務同一個號段的多主機模型在這里就不適用了。我們只能採用單點服務的模式,當某台AllocSvr發生服務不可用時,將該機服務的uid段切換到其它機器來實現容災。這里需要引入一個仲裁服務,探測AllocSvr的服務狀態,決定每個uid段由哪台AllocSvr載入。出於可靠性的考慮,仲裁模塊並不直接操作AllocSvr,而是將載入配置寫到StoreSvr持久化,然後AllocSvr定期訪問StoreSvr讀取最新的載入配置,決定自己的載入狀態

同時,為了避免失聯AllocSvr提供錯誤的服務,返回臟數據,AllocSvr需要跟StoreSvr保持租約。這個租約機制由以下兩個條件組成:

這兩個條件保證了切換時,新AllocSvr肯定在舊AllocSvr下線後才開始提供服務。但這種租約機制也會造成切換的號段存在小段時間的不可服務,不過由於微信後台邏輯層存在重試機制及非同步重試隊列,小段時間的不可服務是用戶無感知的,而且出現租約失效、切換是小概率事件,整體上是可以接受的。

到此講了AllocSvr容災切換的基本原理,接下來會介紹整個seqsvr架構容災架構的演變

最初版本的seqsvr採用了主機+冷備機容災模式:全量的uid空間均勻分成N個Section,連續的若干個Section組成了一個Set,每個Set都有一主一備兩台AllocSvr。正常情況下只有主機提供服務;在主機出故障時,仲裁服務切換主備,原來的主機下線變成備機,原備機變成主機後載入uid號段提供服務。

可能看到前文的敘述,有些同學已經想到這種容災架構。一主機一備機的模型設計簡單,並且具有不錯的可用性——畢竟主備兩台機器同時不可用的概率極低,相信很多後台系統也採用了類似的容災策略。

主備容災存在一些明顯的缺陷,比如備機閑置導致有一半的空閑機器;比如主備切換的時候,備機在瞬間要接受主機所有的請求,容易導致備機過載。既然一主一備容災存在這樣的問題,為什麼一開始還要採用這種容災模型?事實上,架構的選擇往往跟當時的背景有關,seqsvr誕生於微信發展初期,也正是微信快速擴張的時候,選擇一主一備容災模型是出於以下的考慮:

前兩點好懂,人力、機器都不如時間寶貴。而第三點比較有意思,下面展開講下

微信後台絕大部分模塊使用了一個自研的RPC框架,seqsvr也不例外。在這個RPC框架里,調用端讀取本地機器的client配置文件,決定去哪台服務端調用。這種模型對於無狀態的服務端,是很好用的,也很方便實現容災。我們可以在client配置文件裡面寫「對於號段x,可以去SvrA、SvrB、SvrC三台機器的任意一台訪問」,實現三主機容災。

但在seqsvr里,AllocSvr是預分配中間層,並不是無狀態的。而前面我們提到,AllocSvr載入哪些uid號段,是由保存在StoreSvr的載入配置決定的。那麼這時候就尷尬了,業務想要申請某個uid的sequence,Client端其實並不清楚具體去哪台AllocSvr訪問,client配置文件只會跟它說「AllocSvrA、AllocSvrB…這堆機器的某一台會有你想要的sequence」。換句話講,原來負責提供服務的AllocSvrA故障,仲裁服務決定由AllocSvrC來替代AllocSvrA提供服務,Client要如何獲知這個路由信息的變更?

這時候假如我們的AllocSvr採用了主備容災模型的話,事情就變得簡單多了。我們可以在client配置文件里寫:對於某個uid號段,要麼是AllocSvrA載入,要麼是AllocSvrB載入。Client端發起請求時,盡管Client端並不清楚AllocSvrA和AllocSvrB哪一台真正載入了目標uid號段,但是Client端可以先嘗試給其中任意一台AllocSvr發請求,就算這次請求了錯誤的AllocSvr,那麼就知道另外一台是正確的AllocSvr,再發起一次請求即可。

也就是說,對於主備容災模型,最多也只會浪費一次的試探請求來確定AllocSvr的服務狀態,額外消耗少,編碼也簡單。可是,如果Svr端採用了其它復雜的容災策略,那麼基於靜態配置的框架就很難去確定Svr端的服務狀態:Svr發生狀態變更,Client端無法確定應該向哪台Svr發起請求。這也是為什麼一開始選擇了主備容災的原因之一。

在我們的實際運營中,容災1.0架構存在兩個重大的不足:

在主備容災中,Client和AllocSvr需要使用完全一致的配置文件。變更這個配置文件的時候,由於無法實現在同一時間更新給所有的Client和AllocSvr,因此需要非常復雜的人工操作來保證變更的正確性(包括需要使用iptables來做請求轉發,具體的詳情這里不做展開)。

對於第二個問題,常見的方法是用一致性Hash演算法替代主備,一個Set有多台機器,過載機器的請求被分攤到多台機器,容災效果會更好。在seqsvr中使用類似一致性Hash的容災策略也是可行的,只要Client端與仲裁服務都使用完全一樣的一致性Hash演算法,這樣Client端可以啟發式地去嘗試,直到找到正確的AllocSvr。

例如對於某個uid,仲裁服務會優先把它分配到AllocSvrA,如果AllocSvrA掛掉則分配到AllocSvrB,再不行分配到AllocSvrC。那麼Client在訪問AllocSvr時,按照AllocSvrA -> AllocSvrB -> AllocSvrC的順序去訪問,也能實現容災的目的。但這種方法仍然沒有克服前面主備容災面臨的配置文件變更的問題,運營起來也很麻煩。

最後我們另闢蹊徑,採用了一種不同的思路:既然Client端與AllocSvr存在路由狀態不一致的問題,那麼讓AllocSvr把當前的路由狀態傳遞給Client端,打破之前只能根據本地Client配置文件做路由決策的限制,從根本上解決這個問題。

所以在2.0架構中,我們把AllocSvr的路由狀態嵌入到Client請求sequence的響應包中,在不帶來額外的資源消耗的情況下,實現了Client端與AllocSvr之間的路由狀態一致。具體實現方案如下:

seqsvr所有模塊使用了統一的路由表,描述了uid號段到AllocSvr的全映射。這份路由表由仲裁服務根據AllocSvr的服務狀態生成,寫到StoreSvr中,由AllocSvr當作租約讀出,最後在業務返回包里旁路給Client端。

把路由表嵌入到取sequence的請求響應包中,那麼會引入一個類似「先有雞還是先有蛋」的哲學命題:沒有路由表,怎麼知道去哪台AllocSvr取路由表?另外,取sequence是一個超高頻的請求,如何避免嵌入路由表帶來的帶寬消耗?

這里通過在Client端內存緩存路由表以及路由版本號來解決,請求步驟如下:

基於以上的請求步驟,在本地路由表失效的時候,使用少量的重試便可以拉到正確的路由,正常提供服務。

到此把seqsvr的架構設計和演變基本講完了,正是如此簡單優雅的模型,為微信的其它模塊提供了一種簡單可靠的一致性解決方案,支撐著微信五年來的高速發展,相信在可預見的未來仍然會發揮著重要的作用。

                                                                                                                                          本文系 微信後台團隊 ,如有侵犯,請聯系我們立即刪除

我們的官網及論壇:   OpenIM官網

                                     OpenIM官方論壇

8. 微信朋友圈資料庫模式如何設計的

其實微信朋友圈的資料庫設計模式無非就是符合了三種設置模式,其中最常用的是第三種。
第一範式(1NF)
在任何一個關系資料庫中,第一範式(1NF)是對關系模式的基本要求,不滿足第一範式(1NF)的資料庫就不是關系資料庫。
所謂第一範式(1NF)是指資料庫表的每一列都是不可分割的基本數據項,同一列中不能有多個值,即實體中的某個屬性不能有多個值或者不能有重復的屬性。如果出現重復的屬性,就可能需要定義一個新的實體,新的實體由重復的屬性構成,新實體與原實體之間為一對多關系。在第一範式(1NF)中表的每一行只包含一個實例的信息。例如,對於圖3-2 中的員工信息表,不能將員工信息都放在一列中顯示,也不能將其中的兩列或多列在一列中顯示;員工信息表的每一行只表示一個員工的信息,一個員工的信息在表中只出現一次。簡而言之,第一範式就是無重復的列。
第二範式(2NF)
第二範式(2NF)是在第一範式(1NF)的基礎上建立起來的,即滿足第二範式(2NF)必須先滿足第一範式(1NF)。第二範式(2NF)要求資料庫表中的每個實例或行必須可以被惟一地區分。為實現區分通常需要為表加上一個列,以存儲各個實例的惟一標識。如圖3-2 員工信息表中加上了員工編號(emp_id)列,因為每個員工的員工編號是惟一的,因此每個員工可以被惟一區分。這個惟一屬性列被稱為主關鍵字或主鍵、主碼。
第二範式(2NF)要求實體的屬性完全依賴於主關鍵字。所謂完全依賴是指不能存在僅依賴主關鍵字一部分的屬性,如果存在,那麼這個屬性和主關鍵字的這一部分應該分離出來形成一個新的實體,新實體與原實體之間是一對多的關系。為實現區分通常需要為表加上一個列,以存儲各個實例的惟一標識。簡而言之,第二範式就是非主屬性非部分依賴於主關鍵字。
第三範式(3NF)
滿足第三範式(3NF)必須先滿足第二範式(2NF)。簡而言之,第三範式(3NF)要求一個資料庫表中不包含已在其它表中已包含的非主關鍵字信息。例如,存在一個部門信息表,其中每個部門有部門編號(dept_id)、部門名稱、部門簡介等信息。那麼在圖3-2的員工信息表中列出部門編號後就不能再將部門名稱、部門簡介等與部門有關的信息再加入員工信息表中。如果不存在部門信息表,則根據第三範式(3NF)也應該構建它,否則就會有大量的數據冗餘。簡而言之,第三範式就是屬性不依賴於其它非主屬性。

9. 聊天工具包括微信QQ等的伺服器後台資料庫是用什麼資料庫什麼結構什麼方式存儲聊天記錄的

下文是我猜測的:
持久存儲,採用的是mysql
消息中間件 裡面使用了很多nosql技術,
請採納!