專訪淘寶仲明:揭秘阿里運(yùn)維部的故障響應(yīng)機(jī)制
原創(chuàng)【51CTO專訪】在2012年12月4日召開的Velocity China大會(huì)上,大家翹首以盼的、有關(guān)淘寶雙十一的分享,終于正式跟大家見面啦!雖然這一場(chǎng)被安排在了下午5點(diǎn)以后,但現(xiàn)場(chǎng)的觀眾們?nèi)匀缓軣崆?,同時(shí)很多場(chǎng)外的觀眾們也大呼可惜,感嘆自己沒能請(qǐng)假來跟臺(tái)上的講師交流一番。
《購物狂歡節(jié)的運(yùn)維故事》,站在臺(tái)上的講述者是劉勇,花名仲明,阿里資深技術(shù)專家,任職阿里集團(tuán)技術(shù)保障-應(yīng)用運(yùn)維一部。仲明跟其他很多運(yùn)維的不同之處在于,他在進(jìn)入阿里集團(tuán)搞運(yùn)維之前,是一名做開發(fā)的。而很多搞開發(fā)的觀眾們?cè)诼犃怂龅倪@場(chǎng)分享之后,紛紛表示恨不得立刻跑去搞運(yùn)維了。
仲明在會(huì)后已經(jīng)將他本次分享的PPT公布了出來,大家可以在微盤上下載,也可以到微博上跟他交流。而另一方面,51CTO編輯本次也有幸跟仲明進(jìn)行了一些其他方面的溝通,做了下面這個(gè)專訪。
本次專訪的主題是:阿里集團(tuán)運(yùn)維部的發(fā)布、監(jiān)控與故障響應(yīng)。
希望對(duì)大家有所幫助!
---采訪實(shí)錄正文---
軟件發(fā)布
51CTO:先請(qǐng)您介紹一下淘寶運(yùn)維部的代碼部署機(jī)制是怎么樣的吧。首先,你們用什么工具?
仲明:其實(shí)整個(gè)公司的現(xiàn)狀我們是用自己研發(fā)的東西,但是里面也集成了一些第三方的東西。比方說我們一些打包的機(jī)制,用的是rpm。
51CTO:打包用rpm?
仲明:對(duì)。我們部署里面用到了yum這個(gè)工具。其實(shí)yum是基于rpm之上來發(fā)展的,它解決了rpm之間的依賴關(guān)系的問題,這個(gè)我們是集成在里面的。所以基于這個(gè)之上,我們?cè)儆幸粋€(gè)叫做pubfree的東西,專門做發(fā)布的,內(nèi)部運(yùn)維使用的工具系統(tǒng)。
51CTO:專門做publish?
仲明:對(duì)。我們yum解決的問題是說包與包之間的依賴關(guān)系的問題,它解決的是這個(gè),它的使用場(chǎng)景更多的是在單機(jī)上做軟件的升級(jí)和發(fā)布。那么對(duì)pubfree來說,我們要解決的是我們的批量。我們維護(hù)網(wǎng)站的話,有很多集群,每個(gè)集群有幾百臺(tái)機(jī)器,我們?cè)趺磁坎渴?,同時(shí)又解決風(fēng)險(xiǎn)控制的問題,比如說我們的發(fā)布——在生產(chǎn)環(huán)境下——一般走預(yù)發(fā),再走分批發(fā),因?yàn)檫@樣是為了規(guī)避風(fēng)險(xiǎn),比如預(yù)發(fā)有問題的話,能夠及時(shí)的退回來,而不影響用戶。
51CTO:預(yù)發(fā)和分批發(fā)是什么意思?
仲明:預(yù)發(fā)是這樣的,比如說一個(gè)集群有200臺(tái)機(jī)器,先把一臺(tái)機(jī)器摘下來不提供服務(wù),把程序推上去,再驗(yàn)證這個(gè)程序在這個(gè)地方是不是跑的正常。如果跑的正常,那么預(yù)發(fā)就結(jié)束了。然后我們可以在200臺(tái)的機(jī)器里面先推50臺(tái),掛上去提供服務(wù),如果運(yùn)行一切正常,我再會(huì)把其他的全部更新程序。這些是為了規(guī)避一些潛在的隱患,因?yàn)橛幸恍﹩栴},在測(cè)試環(huán)境下,不一定百分之百覆蓋到的。
51CTO:所以你們都是用yum直接做包的操作,而沒有用git或者puppet這樣的機(jī)制?
仲明:沒有。git更多的是一個(gè)源代碼的工具,包括svn也是,它們都是用來管理source code。我們從運(yùn)維的角度,更多的管理是生產(chǎn)環(huán)境的軟件。我們的source code主要是生產(chǎn)環(huán)境之前的過程:不管是Java還是C,都要有一個(gè)build的過程,就是先把source code給check出來,然后build,build完了會(huì)生成一個(gè)要發(fā)布的軟件包,這個(gè)包我們有可能做成rpm的,我們自己做一個(gè)tgz也可以,這個(gè)沒什么差別的。只有這個(gè)做完之后,我們才會(huì)拿這個(gè)做完的包推到生產(chǎn)環(huán)境上去運(yùn)行。
所以生產(chǎn)環(huán)境不會(huì)直接git或者svn。在生產(chǎn)環(huán)境下,我們不會(huì)直接去check出來源代碼在上面build。
51CTO:所以你們都是以軟件包的形式控制的。
仲明:是的??梢园l(fā)布的東西才可以轉(zhuǎn)到生產(chǎn)。
51CTO:那你們這樣比較可控。那版本控制是什么呢,就是軟件包自身的版本機(jī)制?
仲明:對(duì),其實(shí)我們打軟件包的話就會(huì)產(chǎn)生一個(gè)版本,每一次build一個(gè)包,都有一個(gè)新的版本出來。就是說,只要你一build,就會(huì)有一個(gè)新的版本出來,這樣的話你每一個(gè)版本都不一樣的,就可以區(qū)分。那我們每次發(fā)布就會(huì)標(biāo)識(shí),我這一次發(fā)布要發(fā)什么樣的程序過去,我們是看build出來的package的版本,要發(fā)布的人就說,我要發(fā)這個(gè)版本的package。
51CTO:那像您提到的分批發(fā)布,比如說200臺(tái)的服務(wù)器的集群,我先走10臺(tái)再走一半,再全部走,這個(gè)是怎么實(shí)現(xiàn)的?
仲明:這個(gè)就是用剛才我說的pubfree的這個(gè)工具,這個(gè)工具就是解決這樣的問題,第一個(gè)是分批的問題。其實(shí)往一臺(tái)機(jī)器上推程序是很簡單的事情,我基于yum就可以更新這個(gè)程序。但是一個(gè)集群我要怎么管理,這就涉及到第一個(gè)是要分批的事情;第二個(gè)分批即使發(fā)了,你要校驗(yàn)是不是正確,你還可以隨時(shí)停止;第三個(gè)就是你還可以隨時(shí)回滾,比如說第一批發(fā)上去,一check的時(shí)候,發(fā)現(xiàn)有問題,那我還可以退回來。
51CTO:比如說1.0.2發(fā)布了之后有問題,你們是再退回1.0.1?
仲明:差不多,比如說我現(xiàn)在的版本是1.0,我現(xiàn)在要發(fā)一個(gè)新的版本叫1.1,1.1推到一臺(tái)的時(shí),預(yù)發(fā)的時(shí)候,大家沒有發(fā)現(xiàn)問題,我現(xiàn)在推10臺(tái),結(jié)果到了10臺(tái)1.1后,發(fā)現(xiàn)出問題了,這種時(shí)候,我會(huì)把這10臺(tái)回到1.0的狀態(tài)。這就是pubfree這個(gè)工具能夠控制的事情。這個(gè)工具純粹是我們自己開發(fā)的。
51CTO:這么好的工具,以后會(huì)開源嗎?
仲明:這個(gè),有可能會(huì)啊。
51CTO:機(jī)制我大概了解了。那么,整個(gè)發(fā)布的審查過程是怎么樣的?
仲明:審查過程是這樣的,兩種方式結(jié)合,第一是自動(dòng)化的審查,我們每一個(gè)產(chǎn)品有一個(gè)preload的腳本,這個(gè)工具是可以調(diào)用這個(gè)腳本的,這個(gè)腳本運(yùn)行的時(shí)候會(huì)做很多的探測(cè),探測(cè)我的服務(wù)是不是正常的。說個(gè)最簡單的,比如web服務(wù),有可能在web服務(wù)上加一個(gè)腳本或者是一個(gè)內(nèi)部頁面,這個(gè)頁面實(shí)際上是一段程序,程序員寫的,這個(gè)程序會(huì)check我們內(nèi)部的一些接口之類的。check接口會(huì)形成一個(gè)test的邏輯,返回一個(gè)結(jié)果告訴你是否正常,比如一個(gè)產(chǎn)品提供的接口有20個(gè),每個(gè)都check是不是ok的。
51CTO:這部分就是機(jī)器自動(dòng)在那里做么?
仲明:對(duì),這就是一個(gè)程序,可以跑的,一個(gè)程序就可以調(diào)內(nèi)部的任何一個(gè)接口。那么跑完一看,這個(gè)程序就會(huì)反饋一個(gè)狀態(tài)(結(jié)果),我們這個(gè)平臺(tái)會(huì)去調(diào)這個(gè)程序,拿到結(jié)果,來做一個(gè)判斷,如果這20個(gè)接口你認(rèn)為都是ok的,那就ok。這是一個(gè)自動(dòng)化的。
第二個(gè)就是我們的QA(測(cè)試人員)也會(huì)參與這個(gè)過程,他們?nèi)?huì)跑一些核心的測(cè)試用例,一些關(guān)鍵的測(cè)試用例,來看這些用例是不是正常的。如果這些用例跑完都是ok的話,他就認(rèn)為這個(gè)服務(wù)是沒有問題的。
我們說的這個(gè)是預(yù)發(fā)階段,因?yàn)橛脩魶]有參與進(jìn)來。那么我們?cè)陬A(yù)發(fā)階段的這些驗(yàn)證的手段如果都過了,我們認(rèn)為預(yù)發(fā)就ok了。然后我們就推一批機(jī)器,比如說200臺(tái),我先推20臺(tái)。那么推20臺(tái)的時(shí)候,這些機(jī)器就會(huì)對(duì)外提供服務(wù),用戶可以訪問這20臺(tái)機(jī)器,用戶的流量就會(huì)進(jìn)來。流量進(jìn)來之后我們還會(huì)觀察,包括我們的監(jiān)控系統(tǒng)都會(huì)看,去分析這些日志,是不是有錯(cuò)誤日志啊,會(huì)不會(huì)有不正常的日志打出來。即使我們的日志方面沒有任何告警出來,有時(shí)候也有用戶的反饋進(jìn)來。
51CTO:所以這個(gè)階段就是看log和用戶反饋了。
仲明:對(duì)。實(shí)際上這時(shí)候?qū)τ脩羰怯袚p傷的,但是沒辦法,因?yàn)槲覀冎白鐾炅穗x線的測(cè)試,包括我們生產(chǎn)環(huán)境的預(yù)發(fā),用了這么多的檢測(cè)手段,都沒有辦法出發(fā)現(xiàn)這個(gè)問題的話,那么我們唯一能夠規(guī)避的,就是縮小對(duì)用戶的影響,所以這是我們批量發(fā)布的原因。我200臺(tái)分幾次發(fā),第一次發(fā)20臺(tái),也就是十分之一的用戶受到影響,就縮小了影響的范圍。分批發(fā)布的目的是這個(gè)。
如果這一關(guān)還過了的話,那證明我們真的是正常的,這時(shí)候就200臺(tái)機(jī)器全部把新的程序推上去。
51CTO:這個(gè)有不同的級(jí)別嗎?
仲明:是有級(jí)別的。我剛才說的是一個(gè)全流程。其實(shí)分批有一個(gè)東西,我們有一個(gè)名詞叫灰度,我剛才說的分批有幾種情況,一種分批就是我們平時(shí)的操作過程可以做分批,這種分批的間隔是比較短的,有可能是一個(gè)小時(shí);但是我們?nèi)绻f到灰度的話,這個(gè)間隔是很長的,我們一般的灰度至少要求24個(gè)小時(shí)的間隔,就是說,200臺(tái),我發(fā)了20臺(tái)上去,我要觀察24個(gè)小時(shí),然后才可以決定是不是要推新的上去。
灰度實(shí)際上專業(yè)名詞叫bucket test,就是桶檢測(cè),抽一部分用戶去檢測(cè)。這個(gè)有幾種方式,一個(gè)是按流量比例來抽,按流量比例來抽就是隨機(jī)命中的,有可能百分之百的用戶有可能都會(huì)被命中。還有一種情況是根據(jù)用戶來抽,比如說根據(jù)用戶的cookie來判斷是不是該進(jìn)入到桶里面。這是另外一種方式。
我們現(xiàn)在對(duì)于灰度的應(yīng)用是可以選擇的,不是每一次發(fā)布我們都要做灰度,因?yàn)檫@個(gè)代價(jià)太高,會(huì)導(dǎo)致發(fā)布的效率很低,剛才說了一個(gè)灰度至少24小時(shí),這種是對(duì)我們很核心的應(yīng)用。比如說淘寶,淘寶最核心的交易流程上的應(yīng)用我們是這樣控制的,讓你去走灰度。但是對(duì)于非核心應(yīng)用,我們一般不嚴(yán)格要求你去走灰度的。
51CTO:所以一般涉及到支付的更新肯定是要做灰度的。
仲明:對(duì),涉及到交易付款,這些程序的變動(dòng)我們是要求走灰度的。
51CTO:其他的像頁面展示之類的就不用了吧。
仲明:其他的我們就是普通的預(yù)發(fā),分批發(fā)。
51CTO:這種觀察期都在1小時(shí)?
仲明:對(duì),一般控制在一個(gè)小時(shí)之內(nèi),所以這樣效率高很多。
51CTO:那你們的發(fā)布頻率很高啊。
仲明:對(duì),發(fā)布頻率非常高。因?yàn)槲覀兎趾芏鄳?yīng)用,應(yīng)用實(shí)際上說白了就是集群,node group,每個(gè)node group是可以單獨(dú)發(fā)的。像簡單的,比如淘寶網(wǎng),淘寶網(wǎng)就有好幾百個(gè)node group。
51CTO:相當(dāng)于幾百個(gè)業(yè)務(wù)?
仲明:應(yīng)該算是幾百個(gè)service吧。這些服務(wù)當(dāng)然不能單獨(dú)對(duì)外提供一個(gè)業(yè)務(wù)流程,一個(gè)完整的業(yè)務(wù)流程會(huì)把很多服務(wù)串起來,這樣的話,我們是切分成很多這樣的服務(wù)的。一臺(tái)機(jī)器是一個(gè)node,一組機(jī)器做一個(gè)group,里面的每臺(tái)機(jī)器做同樣的事情,這樣的一組node group 提供相同的一個(gè)服務(wù),我們多個(gè)這樣的集群才會(huì)完成一個(gè)完整的業(yè)務(wù)流。這樣一個(gè)完整業(yè)務(wù)流上的每一個(gè)node group都可以單獨(dú)升級(jí)的,所以你就發(fā)現(xiàn)發(fā)布量是很大的。
淘寶網(wǎng)大概有500個(gè)以上node group。每個(gè)node group一周只發(fā)一次的話,一周就要發(fā)幾百次。當(dāng)然,實(shí)際上沒有這么恐怖了,因?yàn)槊恳粋€(gè)node group更新的頻率是不一樣的,越往底層的node group更新的頻率就越低,越接近用戶展現(xiàn)層面的,這個(gè)node group更新頻率就越高。一周一百個(gè)左右是有的。
51CTO:那也很多了,一天是十幾二十個(gè)?其實(shí)挺緊張的吧。
仲明:當(dāng)然我們不是串行的,它有可能會(huì)是并行的,根據(jù)業(yè)務(wù)的相互的關(guān)系來判斷。比如說你兩個(gè)node group之間的變更如果沒有依賴關(guān)系,他們是可以并行去做的。
下一部分:監(jiān)控
#p#
51CTO:那部署這一塊的大概情況基本上您也介紹的差不多了。下一個(gè)問題是有關(guān)監(jiān)控方面,首先主要是想了解一下你們主要都做哪方面的監(jiān)控,可能尤其是網(wǎng)絡(luò)方面,我們會(huì)比較關(guān)注一些。
仲明:這樣來說吧,我們是分三層做監(jiān)控的。一層是基礎(chǔ)的,這種基礎(chǔ)的包括網(wǎng)絡(luò),比如說我們的路由器是不是通的,我們的交換是不是有問題啊,DNS服務(wù)是不是有問題啊,等等,就是一些基礎(chǔ)服務(wù),我們都放在基礎(chǔ)里面,包括我們OS層面的,比如磁盤是不是已經(jīng)快滿了,包括我們內(nèi)存的使用問題,這都屬于基礎(chǔ)層面的,我們叫基礎(chǔ)的監(jiān)控。
基礎(chǔ)層面之上我們叫應(yīng)用監(jiān)控,應(yīng)用監(jiān)控更多監(jiān)控的是這些容器,比如說我們的JVM,是不是跑的正常,是不是有頻繁的GC(垃圾回收),這些是應(yīng)用層面的,包括我們近來的流量是多少,每秒的請(qǐng)求量QPS是多少,是不是QPS有抖動(dòng)。然后我們的RT(反饋時(shí)間),也要監(jiān)控,比如說平時(shí)的反饋時(shí)間都是100ms,是不是有突然的變化,比如超過了200ms我們就要報(bào)警,因?yàn)槲覀兊姆?wù)質(zhì)量已經(jīng)下降了,這是應(yīng)用層面的監(jiān)控。
再往上是業(yè)務(wù)層面的,業(yè)務(wù)層面就很多了,比如說像淘寶的業(yè)務(wù),有創(chuàng)建訂單,用戶下單買這個(gè)東西我們叫創(chuàng)建訂單,那么我會(huì)監(jiān)控這個(gè)創(chuàng)建訂單的數(shù)量。比如說每秒創(chuàng)建多少筆,這個(gè)曲線發(fā)現(xiàn)突然的一個(gè)波動(dòng),本來每秒創(chuàng)建是2000筆的,現(xiàn)在突然一下降成500筆了,這就有問題了,但是這個(gè)東西要通過業(yè)務(wù)層面的數(shù)據(jù)才可以發(fā)現(xiàn)的,不是說系統(tǒng)。系統(tǒng)還很正常,load很低,CPU也沒有什么消耗,但是它已經(jīng)出問題了。
所以說三個(gè)層面去做。
你說的這個(gè)網(wǎng)絡(luò)監(jiān)控,我這么認(rèn)為,一個(gè)是包括內(nèi)部的網(wǎng)絡(luò)狀況的監(jiān)控,第二個(gè)包括外部用戶的網(wǎng)絡(luò)狀態(tài)。從用戶端看我們的行為,用戶端是一個(gè)完整的訪問過程,從客戶端發(fā)起到服務(wù)端響應(yīng),到用戶拿到結(jié)果,這么一個(gè)完整的過程來看,我們的應(yīng)用是不是正常的。
51CTO:對(duì),因?yàn)橛袝r(shí)候我們的監(jiān)控是正常的,用戶訪問起來就有問題。
仲明:在我們公司有兩套手段,一個(gè)就像基調(diào)這個(gè),我們是用了他們的服務(wù)的。他會(huì)從全國各個(gè)點(diǎn)探測(cè)我們的服務(wù)是不是正常的,我們判斷是不是某些區(qū)域出了問題之類的。另外我們公司有一個(gè)工具叫Alibench,它在全國有很多client,在用戶這一端有很多的志愿者會(huì)去裝這個(gè)客戶端。這個(gè)client會(huì)去探測(cè)我們的服務(wù),我們拿到探測(cè)的數(shù)據(jù)進(jìn)行分析,我們的服務(wù)是在DNS解析上有問題,還是在建立連接過程慢,還是什么其他原因。這些數(shù)據(jù)我們可以看到,我們?cè)趺慈?yōu)化我們的網(wǎng)站,是不是有哪些用戶訪問的網(wǎng)站已經(jīng)出現(xiàn)了性能瓶頸。這是我們現(xiàn)在主要使用的兩套工具,來判斷用戶使用網(wǎng)站的體驗(yàn)。
51CTO:剛才您說的應(yīng)用層面和業(yè)務(wù)層面的監(jiān)控,能不能多介紹一下?
仲明:應(yīng)用層面更多的還是從內(nèi)部在看。剛才我說的Alibench和基調(diào),其實(shí)是從用戶的角度去看,完全從用戶端去看。
從服務(wù)提供端來看,我們說應(yīng)用監(jiān)控,大部分都是在這個(gè)地方做的。我們會(huì)在內(nèi)網(wǎng),就是我們的機(jī)房,去發(fā)起這個(gè)探測(cè)。一種是我去探測(cè)我業(yè)務(wù)的接口是不是正常的,模擬用戶行為去看我這個(gè)服務(wù)反饋是不是正常的。
51CTO:這個(gè)也是自己編寫的功能?
仲明:對(duì),這是一種。還有一種我會(huì)檢測(cè)各個(gè)業(yè)務(wù)流程的數(shù)據(jù)。比如說我會(huì)看,現(xiàn)在用戶過來請(qǐng)求任何一個(gè)服務(wù),他的QPS是多少,他的RT怎么樣,反饋出來的響應(yīng)時(shí)間是不是正常的。我還會(huì)監(jiān)控我們的slow query(慢查詢),就是用戶訪問我們網(wǎng)站的時(shí)候,我會(huì)把slow query全部記錄下來。比如說一個(gè)網(wǎng)站,用戶會(huì)有很多的URL來訪問我們的網(wǎng)站,那么我就會(huì)把響應(yīng)時(shí)間超過一秒的,所有的URL 日志里面全部會(huì)拿出來。這個(gè)URL ,一般來說我們會(huì)有一個(gè)比例,比如說我這個(gè)網(wǎng)站每秒的請(qǐng)求數(shù)是1000個(gè),那這個(gè)slow query有可能根據(jù)我網(wǎng)站的特點(diǎn),我應(yīng)用的特點(diǎn),有可能是千分之一的,我會(huì)去監(jiān)測(cè)它。如果這個(gè)slow query出現(xiàn)了波動(dòng),我就知道,我的網(wǎng)站有可能出現(xiàn)了問題,這個(gè)問題有可能來自于一個(gè)新的發(fā)布,我新的一個(gè)程序更新,導(dǎo)致我slow query的比例提升了。這種情況下,我就知道應(yīng)用發(fā)上去之后,網(wǎng)站對(duì)用戶的感受是降低的。因?yàn)槲曳?wù)端去響應(yīng)的時(shí)候,服務(wù)端耗時(shí)已經(jīng)變長了。這種情況下,我們會(huì)把這些slow query抓出來分析,到底是哪些slow query新增了,要求開發(fā)團(tuán)隊(duì)把它改掉。
51CTO:意思是找到造成slow query的那些URL么?
仲明:其實(shí)我們每個(gè)人請(qǐng)求網(wǎng)站的時(shí)候,web服務(wù)端都會(huì)留下一個(gè)日志,這些日志會(huì)記錄下誰來請(qǐng)求我,請(qǐng)求我的哪個(gè)URL地址,你耗費(fèi)了多長時(shí)間。所以我們會(huì)基于這個(gè)東西來做分析。
51CTO:這個(gè)抓取數(shù)據(jù)是用什么做的?
仲明:我們的web容器都會(huì)打一個(gè)日志文件叫access log,這個(gè)里面你是可以配置的,我記錄哪些信息。最主要的信息就是我剛才說的,從哪來的請(qǐng)求,誰來訪問我,訪問我什么URL ,返回的狀態(tài)是什么,花費(fèi)了多長時(shí)間,你是什么agent過來訪問的,是IE瀏覽器還是Chrome瀏覽器,它會(huì)記錄這些信息在里面,那我根據(jù)這些信息可以做很多分析的。
服務(wù)端的東西其實(shí)完全都在我們的控制之內(nèi),因?yàn)橛脩糁灰L問網(wǎng)站就會(huì)留下痕跡,我都可以記錄下來。服務(wù)端是可控的。因?yàn)檫@個(gè)服務(wù)器都在我們手上,包括服務(wù)端的網(wǎng)絡(luò),路由,網(wǎng)關(guān),我們都是可以控制的。但是用戶的感受是什么樣子,比如說用戶的接入端,其實(shí)是不可控的,它的接入我們是不知道的,有的用戶接入網(wǎng)很差,他的體驗(yàn)就會(huì)很差,這個(gè)我們是不知道的。這就只有通過基調(diào)或者Alibench這種工具來看。
51CTO:那除了您提到的響應(yīng)時(shí)間這些,其他監(jiān)控的參數(shù)還有哪些?
仲明:QPS和response time這是最基本的,每個(gè)服務(wù)都會(huì)有。跟業(yè)務(wù)相關(guān)的監(jiān)控,不同的服務(wù)會(huì)不一樣,比如說web容器,QPS和RT是最核心的指標(biāo),代表我是不是可以快速的響應(yīng)用戶需求。再就是看容器的一些狀態(tài),剛才也說過,比如說我們的JVM,是不是頻繁的發(fā)生GC。還有系統(tǒng)層面的很多東西,包括內(nèi)存的使用。JVM實(shí)際上是一個(gè)虛擬機(jī),它自己會(huì)控制一部分內(nèi)存,這部分內(nèi)存的使用是什么狀態(tài),這個(gè)是我們隨時(shí)要跟蹤的。
再往上走,到不同的業(yè)務(wù),比如說我是一個(gè)cache,那跟web容器又不太一樣,cache更多的是看命中率怎么樣,命中率有沒有變化,比如說以前的命中率90%,你現(xiàn)在命中率可能下降到70%,這個(gè)是很危險(xiǎn)的,所以對(duì)于cache來說,我們監(jiān)控的東西就不一樣,首先同樣的我們會(huì)監(jiān)控QPS和RT,另外我們主要看他的命中率怎么樣,數(shù)據(jù)交換出來的速度怎么樣。
還有其他的,比如說像消息隊(duì)列,這個(gè)監(jiān)控又不太一樣了,我要看隊(duì)列的長度。你隊(duì)列太長的話,證明這個(gè)消息在里面等的時(shí)間太長,代表著你的服務(wù)對(duì)用戶的響應(yīng)時(shí)間會(huì)變的越來越長,不夠及時(shí)。
51CTO:怎么算長呢?
仲明:不同的業(yè)務(wù)是不一樣的,因?yàn)椴煌臄?shù)據(jù)我們需要的響應(yīng)時(shí)間是不一樣的。如果你要做隊(duì)列的話,證明你已經(jīng)是異步的處理了,就是說你沒必要同步響應(yīng)用戶,是一個(gè)異步的過程。但是,其實(shí)又有很多的異步服務(wù)是為了響應(yīng)用戶的實(shí)時(shí)服務(wù)的。這是什么意思?比如說用戶現(xiàn)在要下單,下單的時(shí)候,我為什么要加一個(gè)隊(duì)列呢?就是因?yàn)槲液竺嬉蕾囉诹硪粋€(gè)服務(wù),另一個(gè)服務(wù)的速度和我前面服務(wù)的速度不匹配,那就必須有一個(gè)隊(duì)列做緩沖。比如前面的服務(wù)每秒鐘處理1000個(gè)請(qǐng)求,后面服務(wù)每秒鐘只能處理800個(gè)請(qǐng)求,這就出問題了,當(dāng)你達(dá)到峰值一千的話,你發(fā)現(xiàn)后面響應(yīng)不過來了。這種時(shí)候我就有一個(gè)隊(duì)列做緩沖,緩沖你200個(gè),那么因?yàn)槟愕姆?wù)不可能一天一直是滿的,你會(huì)有一個(gè)低谷,稍微峰值一過,低谷來的時(shí)候,就可以把這個(gè)隊(duì)列消化掉。
但是我們又要去看,這個(gè)隊(duì)列到底排多長,如果隊(duì)列太長的話,你發(fā)現(xiàn)就出問題了,比如說我們以前用戶從前端過來,200個(gè)ms回去,當(dāng)我出現(xiàn)隊(duì)列的時(shí)候,有可能變成300個(gè)MS回去,那這個(gè)有可能還是可以接受的。如果說我們的業(yè)務(wù)要求這個(gè)用戶超過了500個(gè)ms就不可以接受,那我們就可以算出隊(duì)列多長是合理的。所以就是根據(jù)不同的業(yè)務(wù)判斷你的隊(duì)列到底多長是一個(gè)可以接受的范圍。
51CTO:500個(gè)ms算是一個(gè)標(biāo)準(zhǔn)嗎?
仲明:不一定了,對(duì)于不同的業(yè)務(wù),不同用戶的忍受程度是不一樣的。從服務(wù)端來說,500個(gè)ms其實(shí)已經(jīng)算不短了,因?yàn)榉?wù)端的響應(yīng)時(shí)間,還要加上用戶網(wǎng)絡(luò)請(qǐng)求、往返的時(shí)間,建立連接的時(shí)間,DNS解析的時(shí)間,在用戶端的反應(yīng)有可能已經(jīng)超過1秒了。
當(dāng)然了,對(duì)用戶來說,一般覺得1秒是可以接受的。就像今天上午Google的那位同學(xué)講的,有可能到3~5秒,用戶才可能不訪問你的網(wǎng)站了,走了。其實(shí)用戶的接受度還是比較高的,1秒是可以接受的。
51CTO:那CDN方面,也是您關(guān)注的范圍吧?
仲明:當(dāng)然是了,CDN也是我們的服務(wù)內(nèi)容之一。CDN的目的很簡單,就是加速——提升我們網(wǎng)站的速度,因?yàn)槲覀円粋€(gè)網(wǎng)頁下來,你發(fā)現(xiàn),特別是像淘寶、天貓這樣的網(wǎng)站,有大量的圖片。你說我們打開Google首頁看一下,內(nèi)容很少,所以很快,但是電子商務(wù)不可能做成那個(gè)樣子,因?yàn)橛脩艟褪菫榱丝瓷唐返?,不可能說圖片沒有了,那這個(gè)用戶的體驗(yàn)就會(huì)下降很多。所以電子商務(wù)網(wǎng)站面臨著很大的問題,用戶一個(gè)頁面打開,請(qǐng)求數(shù)是很多的,他要請(qǐng)求大量的圖片和網(wǎng)頁內(nèi)容。這種情況下,我們就會(huì)很依賴CDN。我們?cè)谌珖己芏帱c(diǎn),用戶拿數(shù)據(jù)的時(shí)候,直接從離他最近的CDN服務(wù)器上拿想要的數(shù)據(jù),這樣的話,用戶的體驗(yàn)就很好,速度就會(huì)很快,所以CDN對(duì)我們很重要。
我們CDN的建設(shè),今年已經(jīng)是超過了兩個(gè)T的帶寬了,就是在峰值的時(shí)候,每秒出去兩個(gè)T的數(shù)據(jù)。
51CTO:那你們現(xiàn)在整個(gè)的監(jiān)控力度是什么樣的,到秒級(jí)還是分鐘級(jí)?
仲明:監(jiān)控力度現(xiàn)在還是在分鐘級(jí)的,一般是兩分鐘計(jì)算一次數(shù)據(jù)。所以說有可能最晚的情況是兩分鐘之前出現(xiàn)問題,我們現(xiàn)在才知道。
51CTO:這樣的話,你們這個(gè)監(jiān)控系統(tǒng)本身的數(shù)據(jù)和處理量也是很大的?
仲明:對(duì)。但是我們現(xiàn)在監(jiān)控系統(tǒng)是分布式處理。所謂分布式處理就是說,有一部分計(jì)算邏輯是在本機(jī)的,就是被監(jiān)控對(duì)象上的。比如說我們有一萬臺(tái)機(jī)器,那我們會(huì)向每臺(tái)機(jī)器要數(shù)據(jù)。如果我把所有的數(shù)據(jù)拉過來再集中運(yùn)算的話,會(huì)有兩個(gè)問題:一個(gè)是我要拉的數(shù)據(jù)量太大,會(huì)占用很多帶寬;第二,去集中運(yùn)算的話,運(yùn)算的成本太高,發(fā)現(xiàn)你會(huì)算不過來,好比我們兩分鐘拉一次數(shù)據(jù)的話,這么多數(shù)據(jù)有可能兩分鐘還沒有算完,這就麻煩大了。
所以我們現(xiàn)在是分兩階段計(jì)算,一階段就是在本地我去找你要數(shù)據(jù)的時(shí)候你計(jì)算一次,這個(gè)時(shí)候你會(huì)發(fā)現(xiàn),你的數(shù)據(jù)量已經(jīng)變的很少了,比如說兩分鐘你要分析,舉個(gè)最簡單的例子,分析日志,access log,兩分鐘的log有可能有幾十個(gè)兆,或者是上百兆的原始日志。如果把100兆拉回去的話,這個(gè)就很麻煩了。所以我們?cè)诒镜貢?huì)做第一次分析,把100兆分析完,分析完之后,有可能形成了兩K的文件。那么1-2K的數(shù)據(jù)上傳到服務(wù)端,然后再去做二次運(yùn)算。二次運(yùn)算基本上是做什么樣的運(yùn)算呢,因?yàn)槲覀兒芏鄶?shù)據(jù)是按集群來看的,在本地這臺(tái)機(jī)器上,只能運(yùn)算本機(jī)的數(shù)據(jù);如果我要看集群的QPS,就是整個(gè)集群的請(qǐng)求數(shù),那我就會(huì)看,在一臺(tái)機(jī)器上我的QPS是多少,再把整個(gè)集群的數(shù)據(jù)拿到一個(gè)集中的監(jiān)控平臺(tái)之后,它會(huì)做二次運(yùn)算,運(yùn)算的時(shí)候就能看出這個(gè)集群的指標(biāo)是一個(gè)什么樣的值。
所以說是兩階段來算的。
51CTO:這樣,基本上兩分鐘拉過來的數(shù)據(jù)可以幾秒處理完?
仲明:很快,在秒級(jí)就處理完了。實(shí)際上你會(huì)發(fā)現(xiàn)在本地運(yùn)算是在毫秒級(jí)的。本地分析是很快的。當(dāng)然,這個(gè)對(duì)本機(jī)會(huì)有一些性能消耗,但是這個(gè)基本上可以忽略不計(jì)的。因?yàn)閮煞昼姴胚\(yùn)行一次。本地做簡單的日志分析是非??斓?。
下一部分:故障響應(yīng)機(jī)制
#p#
51CTO:監(jiān)控這方面有很多細(xì)節(jié),我想很多人都會(huì)感興趣;但是今天時(shí)間有限,我想我們先進(jìn)入下一個(gè)話題吧。您能大概介紹一下淘寶運(yùn)維系統(tǒng)的故障響應(yīng)機(jī)制么?
仲明:故障是這樣的。我們會(huì)對(duì)故障進(jìn)行定級(jí),定級(jí)有P1-P4,四個(gè)等級(jí)的故障級(jí)別。P1是最嚴(yán)重的故障,P4是最輕微的故障,每個(gè)定級(jí)是根據(jù)每個(gè)產(chǎn)品,每個(gè)業(yè)務(wù)來定的。你會(huì)發(fā)現(xiàn)沒有一個(gè)統(tǒng)一的標(biāo)準(zhǔn),它不是說,整個(gè)所有的業(yè)務(wù),什么樣的是P1——不是這樣的。我們會(huì)分開業(yè)務(wù),根據(jù)業(yè)務(wù)的特質(zhì)來確定,你應(yīng)該根據(jù)什么樣的指標(biāo)判斷,這個(gè)是不是一個(gè)P1。
舉個(gè)最簡單的例子,對(duì)于淘寶網(wǎng)來說,很多是看交易的,因?yàn)榻灰资且粋€(gè)很核心的指標(biāo),影響到用戶,這是用戶最核心的指標(biāo):一個(gè)電子商務(wù)網(wǎng)站,用戶不能買東西了,你想想這是什么影響。所以,一個(gè)故障如果影響到用戶在上面買東西了,我們會(huì)根據(jù)這個(gè)比例,你影響了多少用戶買東西,來判斷你是P1還是P2。這是一個(gè)核心指標(biāo)。
P3、P4,這種我們認(rèn)為是比較小的故障是怎么產(chǎn)生的呢,它是跟用戶的體驗(yàn)相關(guān)的。比如說我們有一些用戶投訴過來,用戶的投訴量達(dá)到一定的數(shù)量的時(shí)候,我們就認(rèn)為是一個(gè)P4故障了。比如說我們發(fā)生了幾例相同問題的投訴,同一個(gè)點(diǎn),同一時(shí)間,發(fā)現(xiàn)了好幾例用戶投訴過來,那我們認(rèn)為這是一個(gè)很輕微的P4故障。
為什么定級(jí)呢,有幾個(gè)方面,第一個(gè)就是你剛才問到的響應(yīng)的問題,故障發(fā)生了我們?cè)趺错憫?yīng)。不同的P級(jí),響應(yīng)級(jí)別是不一樣的。像P4的故障,我們會(huì)走到技術(shù)支持,技術(shù)支持會(huì)響應(yīng)它,他們會(huì)排查這個(gè)問題到底是什么樣的,去聯(lián)系投訴的用戶,分析判斷這個(gè)問題。這個(gè)不是很緊急。像P1的故障就很緊急,它的響應(yīng)級(jí)別是不一樣的。如果我們出現(xiàn)了P1的故障,會(huì)需要通報(bào)到副總裁。
51CTO:其實(shí)是上升到一個(gè)行政層面了。
仲明:升級(jí)是深度和廣度兩方面都有的,不僅在行政層面,更大范圍的相關(guān)人員會(huì)知道。為什么非要上升這個(gè)東西呢?是因?yàn)樽尭嗟娜酥?,并且?huì)有更多的人來協(xié)助處理。對(duì)于P1的故障,我們要求一定要在最短的時(shí)間內(nèi)處理掉。那P1的故障,如果問題停留在某個(gè)一線員工手上,他可能無法最快解決故障。有幾種情況,一種是這個(gè)員工不知道公司有哪些資源可以幫助他處理這些問題,這是一個(gè)現(xiàn)實(shí)的狀況,不是所有的員工清楚公司所有的資源。而且,即使他知道,也不知道該找誰,因?yàn)楣敬罅?,上萬人的公司,很難每個(gè)員工明確知道,什么事情找誰。
所以,我們要求有一個(gè)升級(jí)的機(jī)制。像P1級(jí)的故障,我們會(huì)升級(jí)到副總裁的,他需要知道我們的服務(wù)出現(xiàn)了什么重大問題,對(duì)用戶的影響范圍。像P2的故障到總監(jiān)這一層的。P3的故障,到經(jīng)理層,他們會(huì)為一線工程師處理故障提供合適的幫助。
51CTO:是不是可以理解為,故障升級(jí)之后,一線員工已經(jīng)沒有辦法把控了,不能預(yù)估什么時(shí)候可以解決這個(gè)問題?
仲明:一線員工對(duì)系統(tǒng)最熟悉,他們有能力解決問題,但我們的故障信息要透明出來,方便其它部門和管理人員提供幫助,這些會(huì)提升故障處理速度。比如說我們發(fā)生一個(gè)故障,最開始根據(jù)我們的故障定級(jí)判斷是一個(gè)P3級(jí),那么一線的leader就會(huì)指揮一線的員工去處理。但是處理了一小段時(shí)間,比如說處理了20分鐘,發(fā)現(xiàn)還不知道怎么搞定這個(gè)事情,那么這個(gè)時(shí)候,這個(gè)故障就會(huì)發(fā)生變化,它會(huì)從P3升級(jí)到P2故障。這樣的話,他就必須通知到這條線上面的主管,比如說有可能是一個(gè)總監(jiān),他要跟總監(jiān)說明,這個(gè)問題我們已經(jīng)處理了一段時(shí)間,現(xiàn)在還不知道什么時(shí)候能處理完,現(xiàn)在已經(jīng)升級(jí)為P2故障了,那這個(gè)總監(jiān)就會(huì)參與進(jìn)來,調(diào)度相關(guān)的資源,協(xié)助整個(gè)故障處理。尤其當(dāng)你上升到P1故障的時(shí)候,就不僅僅是技術(shù)方面的問題了,包括我們客服的問題,因?yàn)槟銜?huì)有大量的投訴進(jìn)來;包括公關(guān)的問題,我們?cè)趺聪蛴脩艚忉屵@個(gè)問題,這個(gè)范圍就比較大。
51CTO:一開始定級(jí)有一個(gè)算法嗎,還是都是人工定?
仲明:定級(jí)方面,正如我剛才所說,不同的業(yè)務(wù)有不同的指標(biāo)來衡量。但這個(gè)定級(jí)的過程是一個(gè)協(xié)商的過程,也不能說誰說我該給你多少,比如說你這個(gè)業(yè)務(wù)就是按PV來做了,PV降多少就是P1、P2,這樣作為一個(gè)建議當(dāng)然是可以的,不過我們做為互聯(lián)網(wǎng)公司,像這種生產(chǎn)環(huán)境的故障,第一責(zé)任人是我們運(yùn)維的人,但是實(shí)際上,你要知道,大家都是要去負(fù)這個(gè)責(zé)任的,不管是研發(fā)還是測(cè)試,他們相應(yīng)的要去承擔(dān)這樣的責(zé)任。因?yàn)槲覀冎?,一個(gè)故障的發(fā)生有很多的環(huán)節(jié)。有可能是你程序的bug;從測(cè)試的角度也會(huì)承擔(dān)一定的責(zé)任,比如用例覆蓋不全,漏掉了這個(gè)bug;從運(yùn)維的角度也會(huì)承擔(dān)責(zé)任,你雖然有這么一個(gè)bug,但是你在運(yùn)維的過程當(dāng)中,你是不是按照標(biāo)準(zhǔn)的流程執(zhí)行了,這是第一個(gè),第二個(gè)你是不是執(zhí)行到位了,還有的時(shí)候,運(yùn)維的人直接接觸生產(chǎn)環(huán)境,你的操作是不是導(dǎo)致了一些這樣的隱患在里面,都是有可能的。我們故障是共擔(dān)的。
所以在我們的故障定級(jí)這個(gè)方面,一定會(huì)達(dá)成一致的,讓大家心里都清楚。在我服務(wù)出現(xiàn)什么情況的時(shí)候,大家都心里很清楚,這是一個(gè)P1,而不是說有的人認(rèn)為這是一個(gè)P1故障,有的人認(rèn)為這就是一個(gè)小故障,P3。這樣的話,會(huì)不利于我們調(diào)動(dòng)資源。比如說我們出現(xiàn)了一個(gè)P1故障,我們會(huì)要求客服、運(yùn)營、公關(guān)都要快速協(xié)同做事情,如果客服的人認(rèn)為這是一個(gè)P4,我們運(yùn)維的人認(rèn)為是一個(gè)P1,公關(guān)的人認(rèn)為是一個(gè)P3,這就麻煩啦。所以說這個(gè)東西一定是要概念一致的。
51CTO:能談?wù)勀銈冏罱l(fā)生的一次故障么?
仲明:最近是有一個(gè)P2級(jí)的故障。這其實(shí)是一個(gè)很隱藏的故障:我們天貓的一個(gè)服務(wù),把程序發(fā)上去以后,發(fā)現(xiàn)服務(wù)的性能下降了很多,用戶響應(yīng)的時(shí)間變長了。我們發(fā)現(xiàn)這個(gè)問題其實(shí)是在預(yù)發(fā)之后,因?yàn)橐婚_始做預(yù)發(fā)的時(shí)候,沒有用戶流量進(jìn)來,這個(gè)性能下降你感受不到的——測(cè)試請(qǐng)求是很少的。但是我們發(fā)了一批機(jī)器上去,用戶流量進(jìn)來了,發(fā)現(xiàn)性能下降了。
51CTO:在分批發(fā)之后的1個(gè)小時(shí)后發(fā)現(xiàn)了?
仲明:用戶性能下降其實(shí)一發(fā)上去就知道了。我們的服務(wù)都是有監(jiān)控的,它的RT變長了我們是知道的。所以一推上去我們就知道了。那么知道這個(gè)問題了,知道用戶的訪問時(shí)間變長了,但是并不知道是哪有問題了,到底哪里出了問題導(dǎo)致的。對(duì)于我們來說,我們不是去查問題的,我們處理故障都是用最可靠、最快速的方法去解決這個(gè)問題。
很簡單,我不管你是什么問題,回滾程序。這是我們的處理方法。
那么我們就去回滾。但是,回滾完了以后,我們發(fā)現(xiàn)有一些小問題:回滾的版本有一些依賴的包出現(xiàn)了沖突。這是一個(gè)很復(fù)雜的問題。你就發(fā)現(xiàn)這個(gè)服務(wù)還是沒法正常的提供,這個(gè)時(shí)候這個(gè)問題就開始升級(jí)了,就升級(jí)到我這里來了,我就知道這個(gè)問題了,我就會(huì)上線去參與他們的處理,為他們提供一些幫助。當(dāng)時(shí)做了一個(gè)決定,很簡單,我們把流量分流。因?yàn)楫?dāng)時(shí)我們還有正常的服務(wù)存在,那我們就把這些所有已經(jīng)壞掉的這些服務(wù)上面的流量全部切走了。
51CTO:當(dāng)時(shí)已經(jīng)推到多少了?
仲明:大概已經(jīng)到一半的樣子了。我們就把所有的流量切到另外的一個(gè)集群,那個(gè)集群還是正常的,讓它提供服務(wù);這個(gè)集群留下來,大家來排查問題。
這個(gè)時(shí)候你會(huì)發(fā)現(xiàn),故障已經(jīng)結(jié)束了。因?yàn)閷?duì)于用戶已經(jīng)沒有影響了。這時(shí)候我們的系統(tǒng)其實(shí)還是在做恢復(fù)的事情,不過這個(gè)沒關(guān)系,故障到這個(gè)時(shí)候就已經(jīng)close掉了。
51CTO:所以,你們一般還是會(huì)優(yōu)先考慮回滾。
仲明:對(duì)。如果我們?cè)谏a(chǎn)環(huán)境上做了變更、發(fā)布程序之類的,只要出現(xiàn)故障,第一策略就是回滾。因?yàn)檫@個(gè)時(shí)間是很寶貴的,我們總是要找最可靠的方法去把問題解決掉。
51CTO:不管哪個(gè)級(jí)別,都優(yōu)先回滾?
仲明:對(duì),變更引起的故障優(yōu)先回滾。具體是什么問題,我們線下可以分析,因?yàn)槲覀兊南到y(tǒng)會(huì)保留所有的日志。你可以分析,還有我們歷史的監(jiān)控?cái)?shù)據(jù)都是有的。出故障的時(shí)間點(diǎn),這時(shí)候的請(qǐng)求是什么樣,響應(yīng)時(shí)間是什么樣,當(dāng)時(shí)的memory使用是什么樣,IO狀況是什么樣,CPU運(yùn)行是什么樣,各種指標(biāo)你可以看得到,你可以故障結(jié)束后過來分析的。
51CTO:像這種因?yàn)樽兏斐傻膯栴},占的比例大概是多少?
仲明:這個(gè)肯定是比例最高的。
做運(yùn)維的人都知道,變更是萬惡之源。大部分問題都是因?yàn)樽兏鸬?,我們知道引起故障有幾方面,大概可以分為三方面:一方面是發(fā)起變更,程序的變化,不管是什么樣的變化,包括網(wǎng)絡(luò)結(jié)構(gòu)的變化等等,這些都是我們發(fā)起的變化;另一方面是用戶行為的變化,用戶行為的變化也可能導(dǎo)致故障,比如說突然間一個(gè)大的流量進(jìn)來,已經(jīng)超過了你的服務(wù)的處理能力,這個(gè)時(shí)候你就會(huì)出現(xiàn)故障;第三方面就是我們本身誰都沒動(dòng),但是有一臺(tái)交換機(jī),壞了,它跑的時(shí)間太長了,累了,休息一下,那這也有可能導(dǎo)致你的系統(tǒng)出故障。
那這三方面,我們內(nèi)部在運(yùn)維過程當(dāng)中發(fā)起的變更,其實(shí)是導(dǎo)致故障最大的來源,差不多到70~80%這樣。
51CTO:好的,那這次問題就到這里結(jié)束。十分感謝仲明的精彩回答!