RE演進(jìn)之路
手工時代
最早期,我們前端是4層負(fù)載均衡,靜態(tài)資源通過Varnish/Squid緩存,動態(tài)請求跑在LAMP架構(gòu)下。這個時候機(jī)器很少,需要的流程很少,也沒有區(qū)分應(yīng)用運維、系統(tǒng)運維之類的。運維人員也很少,網(wǎng)絡(luò)、機(jī)器和服務(wù)都要負(fù)責(zé)。運維的工作大部分都是靠手工,其實當(dāng)時還沒有成型的運維系統(tǒng),現(xiàn)在很多初創(chuàng)公司都是這種架構(gòu)。
云基礎(chǔ)設(shè)施
隨著業(yè)務(wù)的發(fā)展,我們的架構(gòu)也做出了適當(dāng)?shù)恼{(diào)整。尤其是在步入移動時代以后,移動的流量比重越來越大。接入層不只是Web資源,還包含了很多API接口的服務(wù)。后端的開發(fā)語言也不再局限于PHP,根據(jù)服務(wù)需求引入了Java、Python、C++等,整個業(yè)務(wù)架構(gòu)開始向微服務(wù)化變遷。伴隨業(yè)務(wù)架構(gòu)的變化,底層的基礎(chǔ)架構(gòu)也隨之改變。最大的變化是,2014年中的時候,所有的業(yè)務(wù)已經(jīng)都跑在了云上,如下圖所示。
跑在云上的一個好處是把底層主機(jī)和網(wǎng)絡(luò)抽象化,相當(dāng)于云平臺將主機(jī)創(chuàng)建、網(wǎng)絡(luò)策略修改等封裝到相應(yīng)的系統(tǒng)內(nèi),對用戶提供統(tǒng)一的平臺接口。我們在做維護(hù)的時候,就能把之前很復(fù)雜的流程串連起來。也是在此時,SRE團(tuán)隊初步成立,我們對整個運維相關(guān)的工作做了拆分。云計算部分(由美團(tuán)云負(fù)責(zé))主要負(fù)責(zé)主機(jī)、網(wǎng)絡(luò),還有系統(tǒng)相關(guān)的;SRE對接業(yè)務(wù)側(cè),負(fù)責(zé)機(jī)器的環(huán)境、業(yè)務(wù)側(cè)的架構(gòu)優(yōu)化以及業(yè)務(wù)側(cè)相關(guān)問題的處理。
問題&解決方案
接下來介紹一下我們在做云基礎(chǔ)建設(shè)的過程中,遇到的問題和一些解決方案。
如上圖所示,首先是資源隔離的問題,因為這個問題,造成過幾次故障。我們線上VM的CPU、網(wǎng)卡都是共享的,有一次,壓測的流量很高,把主機(jī)網(wǎng)卡的帶寬基本上都占光了(當(dāng)時的主機(jī)大部分都是千兆的,很容易打滿),同宿主機(jī)的資源都被它爭搶了,其它VM上部署的服務(wù)的響時間變得很大,導(dǎo)致當(dāng)時我們買單的一個服務(wù)(買單的VM和壓測的VM部署在了同一個宿主上)直接掛掉了。
針對這個問題,我們做了兩點,一個是對所有的網(wǎng)絡(luò)資源都做了隔離,針對每個VM作相應(yīng)的配額,另外一個是針對業(yè)務(wù)特性將宿主集群做了拆分。離線業(yè)務(wù),它不考慮CPU的競爭,各個業(yè)務(wù)對于所部署服務(wù)的具體響應(yīng)時間不是很關(guān)注,只要能在一個允許的時間段內(nèi)把業(yè)務(wù)跑完就可以了,我們把這些服務(wù)單獨的放在了一個離線集群。在線業(yè)務(wù),根據(jù)不同業(yè)務(wù)的重要程度,又劃分成了多個小集群。
第二個問題就是VM打散,這個問題初期的時候暴露得并不是很明顯,當(dāng)時整個線上的業(yè)務(wù)還沒有做細(xì)致的服務(wù)化拆分,服務(wù)都部署在一個大集群內(nèi),這種情況下即使VM沒有打散(同一個服務(wù)的多個VM在同一個宿主),某一個宿主掛掉,影響也不是很大。但是隨著業(yè)務(wù)的變化發(fā)展,再做服務(wù)化拆分之后,線上的服務(wù)基本上沒有幾百臺做成一個大集群的情況,都是十幾臺,或者幾十臺這種小集群。
如果我們有一個10臺VM的服務(wù),其中5臺在一個宿主上,那么這個宿主一旦掛掉,服務(wù)整體的承載能力就砍掉了一半,風(fēng)險很高,高峰期如果掉一半,這個業(yè)務(wù)就癱瘓不可用了。針對這個問題,SRE團(tuán)隊跟云計算的同學(xué)做了一個持續(xù)了半年多的優(yōu)化,將VM打散率控制到了90%以上,最終在同一個宿主上,同一個服務(wù),不會多于兩臺VM。
第三個問題,完善調(diào)度成功率。經(jīng)過SRE和云計算同學(xué)的合作努力,現(xiàn)在的成功率已經(jīng)達(dá)到了3個9左右。
c基礎(chǔ)設(shè)施架構(gòu)
上圖是我們云計算基礎(chǔ)設(shè)施網(wǎng)絡(luò)相關(guān)的架構(gòu)圖,可以看到上面是公網(wǎng)的入口,流量接入大部分都是走的BGP鏈路。往下是多機(jī)房間的高速專線,專線的穩(wěn)定性經(jīng)歷了線上大規(guī)模業(yè)務(wù)的校驗,像外賣、團(tuán)購、酒旅等,都是做多機(jī)房部署的。
另外就是高冗余的網(wǎng)絡(luò)架構(gòu),基本上每個節(jié)點都有一個冗余設(shè)備,能保證在其中一臺設(shè)備出現(xiàn)問題的時候,整個流量不受影響。入口和出口接入了一些自研的組件,像MGW、NAT等,使我們對流量的管控變的更靈活。
美團(tuán)點評應(yīng)該是美團(tuán)云最大的用戶,美團(tuán)云能給美團(tuán)點評帶來的收益有完善的API支持、高度定制化資源的隔離、調(diào)度機(jī)制,還有多機(jī)房光纖直連以及較高的資源利用率。
運維自動化
隨著訂單量和機(jī)器數(shù)的高速增長,為了更高效的運維,我們不得不往自動化的方向發(fā)展。
在自動化演進(jìn)的過程中,我們總結(jié)出了自己的一套方法論。
復(fù)雜的事情簡單化。比如引入云平臺,基礎(chǔ)設(shè)備管理都通過云平臺的系統(tǒng)來做,把底層相關(guān)的東西全部封裝,最終暴露給我們的就是接口或Web界面。
簡單的事情標(biāo)準(zhǔn)化。如果你想做流程或者自動化,沒有一個統(tǒng)一標(biāo)準(zhǔn)的話,你要考慮的點就會很多。所以我們在主機(jī)、域名等資源的命名、系統(tǒng)基礎(chǔ)環(huán)境、上下線操作等方面,出了很多的標(biāo)準(zhǔn),這些標(biāo)準(zhǔn)經(jīng)歷線上的實踐打磨最終形成統(tǒng)一的規(guī)范。等標(biāo)準(zhǔn)都成型之后,我們再引入流程,比如創(chuàng)建一些機(jī)器,我會列出需要的操作,然后根據(jù)標(biāo)準(zhǔn)來做SOP,先流程化再自動化。我們通過代碼把手工的工作釋放掉,最終達(dá)到了一個自動化的水準(zhǔn)。
這是服務(wù)樹,它包括線上的云主機(jī)、服務(wù)及服務(wù)負(fù)責(zé)人的映射關(guān)系,根據(jù)不同的層級做一個樹形的展示。它將多個周邊系統(tǒng)進(jìn)行打通,因為上面有標(biāo)簽,通過這個標(biāo)簽?zāi)茏R別唯一的服務(wù)。目前我們打通的系統(tǒng)有配制管理系統(tǒng)、容量系統(tǒng)、監(jiān)控平臺等,還包括線上主機(jī)的登錄權(quán)限。
另外最新的一個成本核算,服務(wù)樹也已經(jīng)打通,通過服務(wù)樹的節(jié)點,只需要進(jìn)行簡單的操作,就能看到每個事業(yè)群的成本情況。
上圖是我們創(chuàng)建機(jī)器的一個簡單流程,首先由技術(shù)人員發(fā)起流程,然后到流程中心,流程中心從服務(wù)樹獲取服務(wù)的基礎(chǔ)信息,然后將信息發(fā)送到運維平臺,運維平臺根據(jù)這些信息去云平臺創(chuàng)建機(jī)器。
之后云平臺會返回到運維平臺,運維平臺將創(chuàng)建好的機(jī)器加到流程中心提供的服務(wù)節(jié)點下,同時調(diào)用配置管理系統(tǒng)對機(jī)器進(jìn)行環(huán)境初始化,初始化完成后會自動添加基礎(chǔ)監(jiān)控信息。之后調(diào)用部署系統(tǒng),對服務(wù)進(jìn)行部署。部署之后,服務(wù)根據(jù)它的服務(wù)的標(biāo)簽,最終注冊到服務(wù)治理平臺,然后就能提供線上服務(wù)了。相當(dāng)于只要技術(shù)人員發(fā)起,整個流程都是能自動完成的。
自動化這塊就簡單介紹這些,下面介紹一下目前的現(xiàn)狀。
數(shù)據(jù)運營
如上圖所示,現(xiàn)如今公司規(guī)模變得很大,我們對此做了一些相應(yīng)的拆分,圖中紅色的部分全部由云平臺來負(fù)責(zé),從最初的接入層到底層的一些基礎(chǔ)設(shè)施,比如機(jī)房、網(wǎng)絡(luò)、主機(jī),全部由云平臺來封裝。中間又拆封了一層,這一層是由SRE來負(fù)責(zé)。
現(xiàn)在流程系統(tǒng)已經(jīng)做得比較完善了,接下來我們新的探索目標(biāo)就是數(shù)據(jù)運營這塊。首先是故障管理,針對線上故障做一個統(tǒng)一管理,包括故障發(fā)生的時間、起因、負(fù)責(zé)人,根據(jù)它的嚴(yán)重程度,分為不同的故障等級。我們也會針對故障的后續(xù)改進(jìn)持續(xù)跟進(jìn)優(yōu)化,保證每一個TODO都能落實。
另外一點,通過故障平臺我們對所有的故障進(jìn)行匯總,系統(tǒng)能根據(jù)匯總的信息對不同的故障進(jìn)行分類,也能總結(jié)出我們線上不同故障類型的占比,進(jìn)而做一些定點的突破。
在故障管理之后,我們又做了一些數(shù)據(jù)挖掘相關(guān)的工作,在初期,我們運維的數(shù)據(jù)主要來自于監(jiān)控平臺或者是業(yè)務(wù)主動上報,而在現(xiàn)在這個階段,我們會主動挖掘一些信息,比如線上服務(wù)的請求量、響應(yīng)時間等來做一些定向的分析。
職責(zé)&使命
如上圖所示,我們的使命從最開始的變更與救火,到現(xiàn)在已經(jīng)逐漸轉(zhuǎn)變?yōu)榉阑鹋c驅(qū)動變革。通過數(shù)據(jù)運營,我們能反向的驅(qū)動業(yè)務(wù)。工作核心是穩(wěn)定性,這一點一直沒變。
我們可以把運維理解為運營維護(hù),運營是指通過經(jīng)驗積累、數(shù)據(jù)分析,推動整體服務(wù)質(zhì)量的改進(jìn);維護(hù)是針對線上的服務(wù),還有業(yè)務(wù)的需求,我們能夠用專業(yè)的技術(shù)來滿足他們。
下面講一下在穩(wěn)定性保障方面的實踐。
業(yè)務(wù)穩(wěn)定性保障實踐
故障起因&實例
首先,我們來總結(jié)下故障的起因,同時舉一些例子來說明具體的情況。
① 變更。美團(tuán)點評線上服務(wù)的日常發(fā)版超過300次,另外還有一些運維的基礎(chǔ)變更,包括網(wǎng)絡(luò)、服務(wù)組件等。舉個例子,線下做變更的時候,我們寫一個簡單的Nginx配置,如下圖所示。
它和線上寫的配置,在紅色部分的順序發(fā)生了變化,如果rewrite的指令在set指令之后,可以生效,結(jié)果符合預(yù)期。當(dāng)我們把rewrite指令前置后,break指令會被先執(zhí)行,會結(jié)束整個重寫過程,rewrite之后的set就不執(zhí)行了,導(dǎo)致配置上線之后,Nginx找不到后端的服務(wù),整個線上的服務(wù)就崩潰了。如果做好充分的灰度,我們就能及時發(fā)現(xiàn)問題并解決,但是我們在上線的過程中缺少了灰度過程。事實上,標(biāo)準(zhǔn)的SOP(標(biāo)準(zhǔn)操作程序)應(yīng)該是上圖中的五步,但是負(fù)責(zé)變更的同學(xué)想當(dāng)然也好,或者是粗心大意也好,在線下測試以后沒有發(fā)現(xiàn)異常,就直接全量上線了,最終釀成大禍。
② 容量。一些大的節(jié)假日或者秒殺搶購都會帶來大流量,異常流量攻擊或者爬蟲抓取也會帶來流量突增。如下圖所示,這是貓眼發(fā)生的一次較大的事故,這個故障主要的原因是最底層的、最后端的服務(wù)容量不到位,在流量發(fā)生大的變化的時候它沒撐住,關(guān)鍵的服務(wù)峰值上漲5倍,DAU相交元旦(前一個歷史峰值)漲了一倍。
主要是兩個問題導(dǎo)致的,一個是我們對于大的活動評估不準(zhǔn)確,還有一個是它的容量不對等。相當(dāng)于前端的應(yīng)用評估是可以撐住的,但是后面的底層沒有撐住,前端的流量都打到后端,后端撐不住,整個服務(wù)就掛了。由此,我們至少要做到兩點,第一要知己,了解自身能承載的容量情況,這點我們可以通過壓測或者一些歷史數(shù)據(jù)的參考獲取到這個容量。第二要知彼,準(zhǔn)確知道前端過來的流量究竟有多大,可以通過運營和技術(shù)的聯(lián)動,在出現(xiàn)一些大的活動或者大的節(jié)假日的時候,通過他們的容量評估和歷史數(shù)據(jù)做出相應(yīng)的判斷,進(jìn)而做一些容量的準(zhǔn)備;另外,要了解下游系統(tǒng)的容量水位,一旦低于本服務(wù)的容量,我們就要做好限流,并且提醒下游服務(wù)做相應(yīng)的容量匹配。
③ 隱患。隱患主要針對系統(tǒng)設(shè)計存在的一些缺陷,還有一些組件的交叉調(diào)用、關(guān)鍵報警的缺失、鏈路容量不對稱等。這類問題是比較難發(fā)現(xiàn)的,需要我們深入進(jìn)行研究。這方面的實例我們可以看下下面這個圖,沒有操作之前,它的數(shù)據(jù)包是沿著綠色的線走的,做了操作之后,部分?jǐn)?shù)據(jù)包就沿著紅色走了。變更前后的主要影響是,紅色鏈路的數(shù)據(jù)包session發(fā)生了變化,因為最初的時候session在IMGW1上,在鏈路發(fā)生變化后,對于TCP有狀態(tài)的連接,再往后就找不到它后端了,數(shù)據(jù)包沒辦法發(fā)送過去,這時候數(shù)據(jù)就丟失掉了,無法連接數(shù)據(jù)庫,這個業(yè)務(wù)就掛掉了。
不過業(yè)務(wù)層在設(shè)計架構(gòu)之初,應(yīng)該考慮到網(wǎng)絡(luò)不穩(wěn)定的情況。針對上面的隱患,大概有三個方法。
第一個就是做全鏈路的演習(xí),模擬一個真實的場景,經(jīng)過模擬演習(xí),還是多多少少能暴露出來一些問題。我們可以針對這些問題,去完善我們的故障預(yù)案、修復(fù)線上漏洞,做演習(xí)的時候也能驗證我們的報警系統(tǒng)是否正常運轉(zhuǎn)。
第二個是SLA,對于服務(wù)定一個比較嚴(yán)格的穩(wěn)定性指標(biāo),并針對這個指標(biāo)持續(xù)不斷的優(yōu)化。比如我們線上HTTP接入的服務(wù),針對accesslog中的狀態(tài)碼和響應(yīng)時間提煉出一個穩(wěn)定性指標(biāo),這對于服務(wù)本身的穩(wěn)定性情況,就多了一個可參考數(shù)值了。穩(wěn)定性指標(biāo)波動服務(wù)必然有問題,這時候我們就要針對它波動的點進(jìn)行相應(yīng)的分析,根據(jù)分析,最終能找到一些隱患。指標(biāo)這塊,要做到用真正的數(shù)據(jù)來反饋出線上的穩(wěn)定性。
第三個就是做故障的管理,每個故障都能找到問題,TODO能落實,各個故障的經(jīng)驗總結(jié),也能共享到多個業(yè)務(wù)線。
經(jīng)驗總結(jié)
事故之前(比如標(biāo)準(zhǔn)SOP、容量評估、流量壓測)的核心就是要防范于未然。
事故之中的核心是快速止損,查找問題是一個相對來說難度比較大,也比較漫長的過程,因為這個時間是不可控的。但是如果我們提前有好的應(yīng)急預(yù)案,就能達(dá)到快速的止損。此外,還要有服務(wù)的自我保護(hù),還有一點,溝通也是很重要的。最開始出現(xiàn)問題的時候,其實是比較亂的,因為大家發(fā)現(xiàn)問題都很急,很多人都在問原因,這時候你問原因是沒有用的,因為大家大部分是不知道,知道的話就能給出解決方案了。所以這時候需要一個完善的溝通機(jī)制,正確的時間反饋正確的消息,反饋的原則是少說表面現(xiàn)象,盡量說一些對于問題定位或者是對于止損方面能夠有幫助的信息。
事故之后,像TODO落實、完善預(yù)案之類的,核心點就是吃一塹長一智,相同的問題不能發(fā)生第二次。
用戶體驗優(yōu)化
首先從用戶端開始,用戶在訪問我們線上業(yè)務(wù)的時候,流量是從公網(wǎng)到私有云,再到Server。公網(wǎng)問題主要有網(wǎng)絡(luò)劫持、多運營商環(huán)境、不可控的公網(wǎng)鏈路等。對于Server的話,主要就是一些傳輸層的協(xié)議,或者應(yīng)用層的協(xié)議的問題,目前大部分業(yè)務(wù)交互還是用的HTTP 1.0/1.1,其實HTTP這個協(xié)議也是需要改進(jìn)的,它不太適合做頻繁的業(yè)務(wù)交互。
針對這些問題,我們都做了一些嘗試:
首先在公網(wǎng)接入這塊啟用BGP,我們現(xiàn)在已經(jīng)做了自建的BGP網(wǎng)絡(luò),不用再關(guān)心多運營商接入的問題。只需要采用BGP網(wǎng)絡(luò),數(shù)據(jù)包在公網(wǎng)傳輸尋址的時候,就可以進(jìn)行最優(yōu)的選路了。
面對劫持問題,我們嘗試了HTTP DNS的方案,同時也在嘗試Shark,就是類似于公網(wǎng)鏈路加速,相當(dāng)于我在用戶的近端部署一個Server,在App上嵌入SDK,用戶通過App發(fā)起的請求不用做DNS解析,而是先發(fā)到Shark(參考之前的博客“美團(tuán)點評移動網(wǎng)絡(luò)優(yōu)化實踐”)上,再由Shark與后端服務(wù)交互。目前通過多種手段的持續(xù)優(yōu)化,劫持問題已經(jīng)少了很多。
針對業(yè)務(wù)交互的協(xié)議,上線了SPDY協(xié)議,對于頻繁交互的業(yè)務(wù)提升還是很明顯的。目前正在測試HTTP 2.0,Server端對于HTTP 2.0的支持還存在少量bug,努力修復(fù)中,希望能早日用上。
未來展望
首先技術(shù)上,目前我們自動化這塊做得比較好,還會持續(xù)做,下一步就是智能化。為什么要智能化呢?其實主要面臨到一個瓶頸點,有些問題是不能通過自動化解決的,比如說前面提到自動故障定位,它的決策性很強(qiáng),需要很多步的決策,并不是通過程序就能直接搞定的。我們現(xiàn)在正在嘗試一些AI的算法,引入人工智能來做突破。
產(chǎn)品方面,我們現(xiàn)在做的所有工具,經(jīng)過線上業(yè)務(wù)大規(guī)模的校驗,正在往產(chǎn)品化的方向發(fā)展,希望能把它做成成型的產(chǎn)品,放在美團(tuán)云上,能給美團(tuán)云的用戶提供服務(wù)。不只服務(wù)于我們自己,也服務(wù)于他人。
最后是技術(shù)架構(gòu),美團(tuán)點評發(fā)展過程中一些疑難問題的解決方案,或者針對挑戰(zhàn)的經(jīng)驗積累,經(jīng)過線上大規(guī)模業(yè)務(wù)的校驗,最終能形成一些成熟的方案,它能為美團(tuán)云上的用戶提供最前沿的技術(shù)參考。
云是大勢所趨,它能把很多底層的問題封裝起來,讓我們有更多精力去做更重要的事情。
評論
查看更多