1. 程式人生 > >【系統架構】億級Web 系統的容錯性實踐【下】

【系統架構】億級Web 系統的容錯性實踐【下】

服務降級,自動遮蔽非核心分支異常

對於一次禮包領取請求,在我們的後端CGI會經過10多個環節和服務的邏輯判斷,包括禮包配置讀取、禮包限量檢查、登陸態校驗、安全保護等等。而這些服務中,就有不可以跳過的核心環節,例如讀取禮包配置的服務,也有非核心環節,例如資料上報對於非核心環節,我們的做法,就是設定一個比較低的超時時間

例如我們其中一個統計上報服務,平均耗時是3ms,那麼我們就將超時時間設定為20ms,一旦超時則旁路掉,繼續按照正常邏輯走業務流程。


服務解耦、物理隔離

雖然,大家都知道一個服務的設計,要儘可能小和分離部署,如此,服務之間的耦合會比較小,一旦某個模組出問題,受到影響的模組就比較少,容錯能力就會更強。可是,從設計之初,就將每一個服務有序的切割地很小,這個需要設計者具備超前的意識,能夠提前意識到業務和系統的發展形態,而實際上,業務的發展往往是比較難以預知的,因為業務的形態會隨著產品的策略的改變而變化。在業務早期流量比較小的時候,通常也沒有足夠的人力和資源,將服務細細的切分。AMS從日請求百萬級的Web系統,逐漸成長為億級,在這個過程中,流量規模增長了100倍,我們經歷了不少服務耦合帶來的陣痛。

服務分離、大服務變成多個小服務

我們常常說,雞蛋不能都放在一個籃子裡。AMS以前是一個比較小的系統(日請求百萬級,在騰訊公司內完全是一個不起眼的小Web系統),因此,很多服務和儲存在早起都是部署在一起的,查詢和發貨服務都放在一起,不管哪一個出問題,都相互影響。後來,我們逐漸的將這些核心的服務和儲存,慢慢地分離出來,細細切分和重新部署。在資料儲存方面,我們將原來3-5個儲存的服務,慢慢地切為20多個獨立部署的儲存。

例如,2016年下半年,我們就將其中一個核心的儲存資料,從1個分離為3個。

這樣做帶來了很多好處:

1:原來主儲存的壓力分流

2穩定性更高,不再是其中一個出問題,影響整個大的模組;

3儲存之間是彼此物理隔離的,即使伺服器硬體故障

,也不會相互影響

輕重分離、物理分離

另外一方面,我們對於一些核心的業務,進行“輕重分離”。例如,我們支援2016年“手Q春節紅包”活動專案的服務叢集。就將負責資訊查詢和紅包禮包發貨的叢集分別獨立部署,資訊查詢的服務相對沒有那麼重要,業務流程比較輕量級,而紅包禮包發貨則屬於非常核心的業務,業務流程比較重。

輕重分離的這個部署方式,可以給我們帶來一些好處:

1查詢叢集即使出問題,也不會影響發貨叢集,保證使用者核心功能正常;

2兩邊的機器和部署的服務基本一致,在緊急的情況下,兩邊的叢集可以相互支援和切換,起到容災的效果;

3每個叢集裡的機器,都是跨機房部署,例如,伺服器都是分佈在ABC三個機房,假設B機房整個網路故障了,反向代理服務會將無法接受服務的B機房機器剔除,然後,剩下AC機房的伺服器仍然可以正常為外界提供服務。

業務層面的容錯

如果系統架構設計層面的“容錯”我們都搭建完善了,那麼再繼續下一層容錯,就需要根據實際的業務來進行,因為,不同的業務擁有不同的業務邏輯特性,也能夠導致業務層面的各種問題。而在業務層面的容錯,簡而言之,避免“人的失誤”。不管一個人做事性格多麼謹慎細心,也總有“手抖”的時候,在不經意間產生“失誤”。AMS是一個活動運營平臺,一個月會上線400多個活動,涉及數以千計的活動配置資訊(包括禮包、規則、活動參與邏輯等等)。在我們的業務場景下,因為種種原因而導致“人的失誤”並不少。

例如,某個運營同學看錯禮包發放的日限量,將原本只允許1天放量100個禮包的資源,錯誤地配置為每天放量200個。這種錯誤是測試同學比較難測試出來的,等到活動真正上線,禮包發放到101個的時候,就報錯了,因為資源池當天已經沒有資源了。雖然,我們的業務告警系統能夠快速捕獲到這個異常(每10分鐘為一個週期,從十多個維度,監控和計算各個活動的成功率、流量波動等等資料),但是,對於騰訊的使用者量級來說,即使隻影響十多分鐘,也可以影響成千上萬的使用者,對於大規模流量的推廣活動,甚至可以影響數十萬使用者了。這樣的話,就很容易就造成嚴重的“現網事故”。

完善的監控系統能夠及時發現問題,防止影響面的進一步擴大和失控,但是,它並不能杜絕現網問題的發生。而真正的根治之法,當然是從起源的地方杜絕這種場景的出現,回到上面“日限量配置錯誤”的例子場景中,使用者在內部管理端釋出活動配置時,就直接提示運營同學,這個配置規則是不對的。

在業界,因為配置引數錯誤而導致的現網重大事故的例子,可以說是多不勝數,“配置引數問題”幾乎可以說是一個業界難題,對於解決或者緩解這種錯誤的發生,並沒有放之四海而皆準的方法,更多的是需要根據具體業務和系統場景,亦步亦趨地逐步建設配套的檢查機制程式或者指令碼。

因此,我們建設了一套強大並且智慧的配置檢查系統,裡面集合了數十種業務的搭配檢查規則,並且檢查規則的數目一直都在增加。這裡規則包括檢查禮包日限量之類比較簡單的規則,也有檢查各種關聯配置引數、相對比較複雜的業務邏輯規則。

另外一方面,流程的執行不能通過“口頭約定”,也應該固化為平臺程式的一部分,例如,活動上線之前,我們要求負責活動的同事需要驗證一下“禮包領取邏輯”,也就是真實的去領取一次禮包。然而,這只是一個“口頭約定”,實際上並不具備強制執行力,如果這位同事因為活動的禮包過多,而漏過其中一個禮包的驗證流程,這種事情也的確偶爾會發生,這個也算是“人的失誤”的另外一種場景。


為了解決問題,這個流程在我們AMS的內部管理端中,是通過程式去保證的,確保這位同事的QQ號碼的確領取過全部的禮包。做法其實挺簡單的,就是讓負責活動的同事設定一個驗證活動的QQ號碼,然後,程式在發貨活動時,程式會自動檢查每一個子活動專案中,是否有這個QQ號碼的活動參與記錄。如果都有參與記錄,則說明這位同事完整地領取了全部禮包。同時,其他模組的驗證和測試,我們也都採用程式和平臺來保證,而不是通過“口頭約定”。


通過程式和系統對業務邏輯和流程的保證,儘可能防止“人的失誤”。

這種業務配置檢查程式,除了可以減少問題的發生,實際上也減輕了測試和驗證活動的工作,可以起到節省人力的效果。不過,業務配置檢查規則的建設並不簡單,邏輯往往比較複雜,因為要防止誤殺

小結

無論是人還是機器,都是會產生“失誤”,只是對於單一個體,發生的概率通常並不大。但是,如果一個系統擁有數百臺伺服器,或者有一項工作有幾百人共同參與,這種“失誤“的概率就被大大提升,失誤很可能就變為一種常態了。機器的故障,儘可能讓系統本身去相容和恢復,人的失誤,儘可能通過程式和系統流程來避免,都儘可能做到”不依賴於人“。

容錯的核心價值,除了增強系統的健壯性外,我覺得是解放技術人員,儘可能讓我們不用凌晨起來處理告警,或享受一個相對平凡閒暇的週末。對於我們來說,要完全做到這點,還有很長的路要走,與君共勉。