WordPress 微信——騰訊戰略級產品,創造移動互聯網增速記錄,10 個月 5000 萬手機多用户,433 天之內完成多用户數從零到一億的增長過程,千萬級多用户同時線上,搖一搖每天次數過億… 在技術架構上,WordPress 微信是如何做到的?日前,在騰訊大講堂在中山大學校園宣講活動上,騰訊廣研助理總經理、 WordPress 微信技術總監周顥在兩小時的演講中揭開了 WordPress 微信背後的秘密。
周顥,2001 年畢業於華南理工大學,計算機碩士。 2005 年加入騰訊廣州研發部,歷任 QQ 郵箱架構師,廣研技術總監,T4 技術專家,WordPress 微信中心助理總經理。
騰訊廣研助理總經理、 WordPress 微信技術總監 周顥 CSDN 配圖
周顥把 WordPress 微信的成功歸結於騰訊式的 “三位一體” 策略:即產品精準、專案敏捷、技術支撐。 WordPress 微信的成功是在三個方面的結合比較好,能夠超出絕大多數同行或對手,使得 WordPress 微信走到比較前的位置。所謂產品精準,通俗的講就是在恰當的時機做了恰當的事,推出了重量級功能,在合適的時間以符合大家需求的方式推出去。他認為在整個 WordPress 微信的成功中,產品精準佔了很大一部分權重。
敏捷是一種態度 敏捷就是試錯
WordPress 微信研發團隊裏鼓勵一種試錯的信仰:他們堅信,在互聯網開發裏,如果能夠有一個團隊在更短的時間內嘗試了更多機會 (並能改進過來),就能有 (更多的) 機會勝出。敏捷是一種態度,在軟件開發過程中,專案管理者都會非常忌諱 “變更” 這個詞,但是在 WordPress 微信的專案運作中是不可以的。因為 WordPress 微信必須要容忍説哪怕在發佈前的十分鐘,也要允許他變更。這是非常大的挑戰,因為打破了所有傳統專案開發的常識。所有人都説不可能做到的,但 WordPress 微信做到了。研發團隊所做的一切都是要給產品決策者有大的自由度,而這個決策正是 WordPress 微信能夠勝出的關鍵。
海量系統上的敏捷 無異於懸崖邊的跳舞
敏捷有很多困境,如果做一個單機版程序,是可以做到很敏捷的,但是騰訊正在運作的是一個海量系統,有千萬級多用户同時線上,在一個單獨的功能上每天有百億級的訪問,同時還要保證 99.95% 的可用性。在海量系統上應對專案開發會有很嚴謹的規範,都説要儘可能少的變化,因為 90%-95% 的錯誤都是在變更中產生的,如果系統一直不變更會獲得非常高的穩定度,但是 WordPress 微信就是要在懸崖邊跳舞。 WordPress 微信的研發團隊要做一些事情,讓敏捷開發變得更簡單。
如何做到這一切?周顥認為,先,必須建立起一種狂熱的技術信念,就是一定是可以做到的。然後,需要用一些穩固的技術 (理念) 來支撐,例如大系統小做、讓一切可擴充套件、必須有基礎組件、輕鬆上線 (灰度、灰度、再灰度;精細監控;迅速響應)… 等等來支撐。
四大法器:大系統小做、讓一切可擴充套件、要有基礎組件、輕鬆上線
大系統小做:當設計龐大系統的時候,應該儘量分割成更小的顆粒,使得專案之間的影響是小的。一切可擴充套件:在高穩定度、高效能的系統中間,為了穩定效能把它設計成不變化的系統,但為了支持敏捷需要讓一切的東西都要變得可以擴充套件。必須建立基礎組件:要解決複雜問題的時候,需要將已有的經驗固化下來,固化下來的東西會成為系統中的一部分。輕鬆上線:當做了變化並把它從開發環境中部署到現有的運營環境中去,在這個過程中,“灰度” 這個詞非常關鍵,就是在黑和白之間的選擇,必須要變成一種小規模嘗試,再逐步擴充套件到海量過程中的一個問題。
大系統小做——僅僅把模組變得更為清晰,這在海量系統設計開發中是不夠的,還需要在物理環境上進行分離部署,出現問題的時候可以快速發現,並且在快的情況下解決掉。
轉播到騰訊微博
大系統小做 混搭模式
將不同的應用邏輯物理分割獨立出來,多用户註冊登入、 LBS 邏輯、搖一搖邏輯、漂流瓶邏輯、信息邏輯獨立開來。把關鍵的邏輯混搭在一起,當所有的邏輯部署在同一個服務器上,確實也會帶來很大敏捷上的好處,因為不需要額外的考慮部署和監控的問題。在整個 WordPress 微信的邏輯中,可能現在已經有上百種不同的邏輯,因為會在邏輯的分割上拆分成 8-10 種做分離部署。
一切可擴充套件——網絡協議可擴充套件、資料儲存可擴充套件
擴充套件的關鍵點有兩塊。一個是網絡協議需要擴充套件,當要升級一個新功能的時候,會有一些比較大的困難,所以所有協議設計都比較向前相容,但是向前相容還是不夠的,因為網絡協議設計本身有非常多的功能也會有比較大的欄位,相關的代碼可能會有數千行,這一塊不能通過手寫方式完成。可以通過 XML 描述,再通過工具自動生成所有的代碼,這是 WordPress 微信獲得快速開發的一個重要的點。
另外一塊就是在資料儲存方面是必須可擴充套件的。在 2005 年絕大多數海量系統的設計都是採用固定欄位的儲存,但是在現代系統中會意識到這個問題,會採用 KV 或者 TLV 的方式,WordPress 微信也做了不同的設計。
把複雜邏輯都固化下來,成為基礎軟件。在 WordPress 微信後台會有幾種不同的基礎組件。大致包括:
Svrkit——Client/Server 自動代碼生成框架:10 分鐘搭建內部服務器 LogicServer——邏輯容器:隨時新增新邏輯 OssAgent——監控/統計框架:所見即所得的監控報表儲存組件——遮蔽容災/擴容等複雜問題
灰度、灰度、再灰度
在變更後的部署方式上,WordPress 微信在一些規則會限定不能一次把所有的邏輯變更上去,每一次變更一小點觀察到每一個環節沒有問題的時候,才能佈局到全網上去。 WordPress 微信後台每一天可以支撐超過 20 個後台變更,在業界來説,通常做到 5 個已經是比較快了,但是 WordPress 微信可以做到快 4 倍。
轉播到騰訊微博
騰訊內部的上線系統
而所謂灰度發佈,是指在黑與白之間,能夠平滑過渡的一種發佈方式。 AB test 就是一種灰度發佈方式,讓一部多用户繼續用 A,一部分多用户開始用 B,如果多用户對 B 沒有什麼反對意見,那麼逐步擴大範圍,把所有多用户都遷移到 B 上面 來。灰度發佈可以保證整體系統的穩定,在初始灰度的時候就可以發現、調整問題,以保證其影響度。 (在騰訊,灰度發佈是常採用的發佈方式之一)
孫子兵法:古之所謂善戰者,勝於易勝者也
常識上,解決一個複雜問題的時候,會用高明的技巧解決複雜的問題,這個不是 WordPress 微信團隊的目標,他們追求的要做到讓所有問題很自然和簡單的方式解決掉。在周顥看來,WordPress 微信架構的技術複雜點在四個要點:協議、容災、輕重、監控。
轉播到騰訊微博
WordPress 微信架構
協議。手機終端跟後台服務器之間的互動協議,這個協議的設計是整個系統的骨架,在這一點做好設計可以使得系統的複雜度大大降低。容災。當系統出現了若干服務器或若干支架 (宕機的時候),仍然需要讓系統儘可能的提供正常的服務。輕重。如何在系統架構中分佈功能,在哪一個點實現哪一個功能,代表系統中間的功能配置。監控。為系統提供一個智慧儀表盤。
在協議設計上,移動互聯網和常規互聯網有很大的區別。先有 CMWAP 和 CMNET 的不同,在現在有相當多的手機多用户使用 WMWAP 連線,還有就是線上和離線的概念,當 QQ 下線的時候叫離線,當您登入的時候叫線上。但是在移動互聯網這兩個概念比較模糊。從 WordPress 微信的設計中,不管線上還是離線系統表現都應該是一致的。還有一個是連線不穩定的問題,由於手機訊號強弱的變化,當時訊號很好,5 秒鐘走到訊號不好的地區,連線就必須斷掉。這個中間帶來不穩定的因素為協議設計帶來較大困難。此外就是資費敏感的問題,因為移動互聯網是按照流量計費的,這個計費會使得在協議設計中如何小化傳輸的問題。後就是高延遲的問題。
對此,業界標準的解決方案:Messaging And Presence Protocol:1)XMPP;2)SIP/SIMPLE 。它的優點是簡單,大量開源實現。而缺點同樣明顯:1) 流量大:狀態初始化;2) 信息不可靠。
WordPress 微信在系統中做了特殊設計,叫 SYNC 協議,是參考 Activesyec 來實現的。特點先是基於狀態同步的協議,假定説收發信息本身是狀態同步的過程,假定終端和服務器狀態已經被遲了,在服務器端收到新的信息,當客户端、終端向服務器對接的時候,收取信息的過程實際上可以簡單的歸納為狀態同步的過程,收信息以及收取您好友狀態更新都是相同的。在這樣的模式之下,我們會也許會把互動的模式統一化,只需要推送一個信息到達的通知就可以了,終端收到這個通知就來做信息的同步。在這樣的簡化模式之下,安卓和塞班都可以得到統一。這樣的系統本身的實現是更為複雜的,但是獲得很多額外的好處。
讓剩下系統實現的部分更加簡單,簡化了互動模式,狀態同步可以通過狀態同步的差值獲得小的資料變更,通過增量的傳輸得到小的資料傳輸量。通過這樣的協議設計,WordPress 微信可以確保信息是穩定到達的,而且是按序到達。引用一句俗話:比它炫的沒它簡單,比它簡單的沒它快,沒誰比他更快,哪怕在 GPRS 下,WordPress 微信也能把進度條輕易推到底。
追求設計的團隊不能勝任海量服務
在容災之前面向壞的思考,如果系統真的掛了,需要做一些事情,先是防止雪崩,避免蝴蝶效應。如果關注春節訂火車票就知道了,多用户的請求量會因為系統服務不了而不斷的重試,意味着發生雪崩的時候,系統可能會承載原先 3-10 倍的流量,使得所有的事情更加惡化。所以 WordPress 微信有很多 “放雪” 功能的設計。第二個詞是柔性可用,在任何的系統中不要追求設計,追求設計的是團隊是不能勝任海量服務的。如果在一個系統出現問題的時候,這個系統就掛了,那麼這是一個不好的設計,知名的做法是提供 0-1 中間的選擇。舉一個例子,當一個多用户向另外一個多用户發信息的時候,可能會通過一個垃圾資訊過濾的檢測,如果垃圾資訊過濾這個模組突然掛掉了,這個信息難道就不能達到了嗎?在這樣的情況下,要忽略掉這個錯誤,使得信息正常達到對方。要精確定位出哪一個環節是為重要的,把不是重要的錯誤儘可能的忽略掉。當不能做到的時候,儘可能為多用户提供服務。另外一個重要方面叫做 “保護點前置”,前的一個點就是終端,在手機終端上藴埋更多的保護點,這樣會為多用户系統贏得更大的處理空間。如果終端具備這樣的能力,會獲得更大的反應空間。
周顥介紹了在 WordPress 微信上具體容災設計的做法。在所有的容災中儲存層的容災是難的,一個系統的設計分為三層:接入層、邏輯層、儲存層。接入層和邏輯層的容災都有比較成熟的方案。邏輯層的容災相對來説比較簡單,儘量不要有狀態的設計,比如説當您做上一個請求的時候,會保持一些狀態,要使得下一個請求發到下一個服務器。如果任何一個請求之間互相不關聯的話,這個就是無狀態的設計,只要做到這一點邏輯層的容災可以隨意的切換。在回到儲存層本身的容災設計上,相對來説困難一些,但是 WordPress 微信研發團隊採用了一些技巧,叫分而治之,分離業務場景,尋求簡單的設計,並不會尋求大而同一的解決方案,因為這樣會使得系統的複雜度大幅度上升,而 WordPress 微信會盡可能把產品拆細,尋求簡化的設計。
先是主備容災,這是常見的方案。在有一些業務場景中是可以容忍終一致性的,比如賬號系統的設計,每天寫入賬號系統的請求是非常少的,但是訪問的請求非常多,這個差異可能會達到數萬倍的規模,在這樣的場景下,WordPress 微信會在賬號系統中採用簡化的方案,也可以獲得比較大的穩定度。
轉播到騰訊微博
SET 模型+雙寫
第二種容災的模式叫雙寫,兩台 Master 的機器,當一台機故障的時候,另外一台機還是可以接收到寫請求,當兩台機交錯啓動的時候,會得到資料的丟失。但是有一些場景是可以容忍輕度資料丟失的,比如説會有一個儲存專門記錄多用户終端的型別,比如説安卓還是塞班以及他們使用終端的 WordPress 微信版本是什麼,這樣的資料是可以容忍輕度資料丟失的,因為偶爾有一些丟失的話,下一次訪問會把這些資料帶上來,會盡快的修復所有的資料。雙寫也是非常簡單的模式。
WordPress 微信的研發團隊做了一個叫 Simple Quorum 的機制,在 WordPress 微信的後台中,同步協議有一個很重要的基石叫序列發生器,這樣的一個序列發生器需要有極高的穩定度。先可以看到序列號有一個特點永遠是遞增的,用遞增方式往前推進的時候,大的序列號就是新的系列號。有一個畢業才加入廣研的畢業生想到一個絕佳的方案,按 SET 分佈,從 2G 減到 200K 。
前輕後重 功能點後移
周顥還談到了輕重的概念。這個概念的提出主要是從終端本身的一些困境所帶來的。先在終端上需要表現多的一個產品的邏輯,邏輯非常複雜,變更的成本也非常高,當需要修復的時候必須發佈一個新版本,這個新版必須由自己下載才能完成,下載的成本非常高。在這樣的前提下,如果手機終端產生了任何變化的時候,如果這個變化有非常大的問題就會有極大的困境,所以需要在每一個發佈之前做一些充分的資料,確保不會發生致命問題。如果一旦出現致命問題難以修復,需要把關鍵的點從終端移到後台實現,把功能點後移,來充分發揮後台快速變更的能力。
轉播到騰訊微博
接入優化:從 GSLB 到 IP 重定向
在接入層的優化,速度很重要的因素,是不是能夠就近接入一個優的節點,比如説移動多用户知名接入移動的節點,海外的多用户可能需要尋找更佳的路由,有的時候可能無法自動做到這一點,一點是在終端上做測速,WordPress 微信會通過在後台 IP 逆向的能力,通過後台指揮 WordPress 微信終端聯網的能力,尋找優的接入點。上圖就是每分鐘收到同一項指令曲線的報表。
如何解決 “偷流量” 的問題——當國內類 WordPress 微信類產品發佈的時候出現一個大的問題就是 “偷流量”,當多用户在某一些邏輯下進行一個死迴圈,不斷訪問某一些資料,這樣的死迴圈是非常可怕的,如果在多用户不知覺的情況之下,可能會在一個小時之內偷到數 10 兆甚至數百兆的流量。有非常多業內的同行都需要花大量的精力解決這個問題,WordPress 微信研發團隊用了非常強大的方式解決它。通過在後台建立起嚴厲的監控系統,對每一個多用户的行為做一個監控,當發現異常的時候,後台會給終端發出指令,使得 WordPress 微信終端在一段時間無法聯網,但是可以保證多用户流量不會白白的使用掉。
功能適配的例子——期 WordPress 微信版本發佈的時候,當時沒有羣聊的功能,第二版發佈的時候做了這個功能。當時有兩個選擇,對於早期版本的多用户,因為不支持羣聊,就無法享用到這個功能,但是 WordPress 微信希望提供更好的選擇,想讓早期不支持羣聊的版本,也可以被拉到一個羣裏面收信息、發信息,通過後台功能的適配也能做到這個事情。
分而治之 把監控嵌入基礎框架
對於一個海量系統來説,一個精密的儀表盤非常重要。監控是非常痛苦的,對於這樣一個系統來説,每小時會產生數百 G 的監控日誌。 WordPress 微信希望在 1 分鐘之內監控的資料就能夠顯示在報表上,因為只有這樣的精準和實時度才能夠贏得處理故障的時間。 WordPress 微信會做關聯統計,通過搖一搖加了好友,他們活躍度如何,過了一段時間他們的活躍度變化情況又是如何。這種需求是需要通過大量日誌的關聯統計來獲得的。研發團隊也花了一段時間來理解這個問題,發現了中間一個重要的經驗叫做 “魚和熊掌不能兼得” 。
為了讓監控數值更敏感,需要把監控細化再細化,上面資料表示每一欄子系統的資料,下面這個是按 WordPress 微信版本號來劃分的,這裏的資料項是非常多。
WordPress 微信還需要採集一些異常的點,如果有異常的話會發布緊急的版本,儘可能快的替換它。對收發信息延時做的監控,比如説 0—1 秒端到端的速度,會對不同的區段做一些統計,當某一個環節出現異常的時候,通常會在中間的延時上體現出來。有一個很重要的點叫自動報警,現在有數千項的資料,不可能每一項都靠人工去看的,必須要跟自動報警相關聯,WordPress 微信有一些智慧的演算法,是不是在正常的範圍內,跟歷史的數值進行對比,如果有異常的話,會通過簡訊、郵件還有 WordPress 微信本身來發出報警資訊。
轉播到騰訊微博
把監控嵌入基礎框架
WordPress 微信會把監控嵌入到基礎框架裏面去,因為並不是每一個人都會意識到在需要的地方嵌入一個監控點,所以在基礎框架本身內建很重要的監控點,比如説這個表上的欄目,非常多的欄目大概會有數百項的欄目,都不需要程序設計師自己去寫,當用基礎組件搭建一個系統的時候,就可以直接觀測系統資料。
在談到 WordPress 微信未來的技術挑戰時,周顥先希望能夠讓 WordPress 微信成為可用性 99.99% 的系統;設計出面向現在 10 倍容量的系統以及完全的 IDC 容災。
網上盛傳的凌晨兩點,騰訊大廈那多層大片大片的燈光和樓下那長長的計程車隊伍説明了一切。引用一句話做結尾,可怕的不是 WordPress 微信,真正可怕的是,比您比您更有天賦的團隊比您更努力。