大規(guī)模微服務(wù)場景下的性能問題定位與優(yōu)化

分享下劉超老師的一篇文章,好好學(xué)習(xí)剑辫。

今天我的主題是在微服務(wù)場景下的一個性能問題的定位優(yōu)化,那么今天會講一個我們其實出現(xiàn)的一個真實的一個場景渠欺,然后其實還是花了蠻長時間妹蔽,然后把這個東西才定位到一個具體的問題。

image

現(xiàn)在云原生微服務(wù)架構(gòu)特別的火挠将,有非常多的優(yōu)勢胳岂,比如說這里面寫的快速迭代,高并發(fā)舔稀,可維護(hù)乳丰,可擴(kuò)展,灰度發(fā)布镶蹋,高可用成艘,這些詞大家都耳熟能詳赏半,這些就不用細(xì)說了。

image

但是微服務(wù)不是沒有成本的淆两,如果說單體應(yīng)用的復(fù)雜度大概是10的話断箫,上了微服務(wù)可能是變成100,可能是十倍的復(fù)雜度提高秋冰,需要投入大量的人去做這個事兒仲义,并且需要一定的支撐系統(tǒng)和工具鏈,才能將這些復(fù)雜性降下來剑勾。

我這邊總結(jié)了一下微服務(wù)實施之后埃撵,會大概率出現(xiàn)以下的痛點:

第一:服務(wù)依賴的管理,就是一個服務(wù)到底調(diào)用了哪些虽另,被哪些服務(wù)調(diào)用暂刘,如果依賴管理比較混亂,就會比較痛苦捂刺,比如說你要發(fā)布一個應(yīng)用谣拣,你可能不知道這個應(yīng)用被誰依賴了,有沒有有一個特別關(guān)鍵的應(yīng)用在依賴于我這個應(yīng)用族展,會不會我升級了以后是否會引發(fā)關(guān)鍵業(yè)務(wù)的不穩(wěn)定森缠,是應(yīng)該白天發(fā)布,還是凌晨發(fā)布仪缸,這個時候我們就特別需要希望有一個系統(tǒng)能夠看到任何一個服務(wù)都被哪些服務(wù)依賴以及依賴于哪些服務(wù)贵涵。

第二:調(diào)用統(tǒng)計問題,對于調(diào)用記錄有一個統(tǒng)計和告警恰画,例如有沒有接口突然調(diào)用失敗率增高宾茂,有沒有接口突然時延增長,都應(yīng)該及早發(fā)現(xiàn)锣尉,而不能因為因為一次發(fā)布引入一個bug刻炒,導(dǎo)致時延變長但無人知曉,等到流量一來自沧,直接就可能壓掛了坟奥。再就是有沒有接口再也沒有人調(diào)用,這個接口是否可以下線拇厢,這在接口升級的時候爱谁,常常采取先添加接口,再下線接口的方式孝偎,就需要這樣一個統(tǒng)計系統(tǒng)访敌。

第三:接口規(guī)范問題,各個團(tuán)隊開發(fā)出來的各個服務(wù)的接口是否符合統(tǒng)一的接口規(guī)范衣盾,有沒有統(tǒng)一的地方去看接暴露出來的接口寺旺?如果說有的接口不遵守規(guī)范爷抓,那么是不是時候會在同一個地方能看到,然后去盡早的去發(fā)現(xiàn)這個問題阻塑。

第四:安全管理蓝撇,很多企業(yè)往往通過白名單通過配置中心配到各個服務(wù)里面去的,比如說支付這個服務(wù)不是所有服務(wù)都能調(diào)用的陈莽,只有部分服務(wù)可以調(diào)用他渤昌。這些配置原來都是散落在這個服務(wù)里面去的,各自為站走搁,有可能一不小心就配置錯了或者漏了独柑,應(yīng)該能訪問的訪問不了,不該訪問的能夠訪問了私植,但是沒有人察覺忌栅。

第五,熔斷限流降級這些服務(wù)治理能力兵琳。雖然有很多開源組件可以做這些事情狂秘,但是需要寫大量重復(fù)代碼去做骇径,同樣是散落在各個地方躯肌。

第六,接口測試問題破衔,我們?nèi)绾伪WC在不斷的拆合的過程中不會引入新的bug清女,這其實是比較頭疼的一個事情,所以需要一個比較大的一個測試集合晰筛,就需要一個測試平臺來保證嫡丙。

第七,灰度發(fā)布問題读第,很多公司做灰度發(fā)布曙博,都是通過代碼里面寫if-else做的,當(dāng)什么條件滿足的時候怜瞒,走這個邏輯父泳,當(dāng)時什么條件滿足的時候,走那個邏輯吴汪,這個時候也是相對比較痛苦的惠窄。

第八,壓力測試問題漾橙,這一般是實施微服務(wù)的后期杆融,當(dāng)需要面對大規(guī)模流量的時候,才會引入進(jìn)來的霜运。一開始線上大促的時候脾歇,基本處于這種一臉蒙蒋腮,靠運氣的這種狀態(tài),心里壓根都沒有譜藕各,必須要通過壓力測試去做這個事兒徽惋。

第九,調(diào)用鏈分析問題座韵,一旦出現(xiàn)慢的時候险绘,相對比較難以發(fā)現(xiàn)慢的點,尤其是當(dāng)服務(wù)數(shù)目多誉碴,調(diào)用鏈長了之后宦棺。

第十,測試環(huán)境治理黔帕。服務(wù)數(shù)目增多了代咸,大家都用了容器,帶來的好處就是部署的特別方便成黄,一個編排就能啟動一套系統(tǒng)呐芥,但是同時也帶來一個痛苦,其實我們從云的時候就有這個痛苦奋岁,一旦放給大家的權(quán)限讓大家可以隨時部署思瘟,對于資源的使用就控制不住了,大家誰都想啟動一個新的環(huán)境闻伶,自己的測試環(huán)境和別人都不在一塊滨攻。如果說只有幾個容器,那么每次都重新部署一個新環(huán)境蓝翰,這沒有問題光绕,但是如果服務(wù)特別多的時候,例如一百個容器的時候畜份,這時候全量部署比較困難诞帐。

image

為了解決這些問題,需要配備比較復(fù)雜的工具集合:容器平臺負(fù)責(zé)聲明式部署爆雹,持續(xù)集成和測試平臺負(fù)責(zé)灰度發(fā)布和測試集合的維護(hù)停蕉,API網(wǎng)關(guān)負(fù)責(zé)入口流量的接入,微服務(wù)框架負(fù)責(zé)微服務(wù)之間的相互調(diào)用顶别,管理和治理谷徙,分布式事物負(fù)責(zé)拆分后的事務(wù)問題,APM性能管理負(fù)責(zé)調(diào)用鏈分析驯绎。我們后面也能看到這些組件在定位問題的過程中都起到了什么樣子的作用完慧。

微服務(wù)的拆分過程并不是一蹴而就的,我們發(fā)現(xiàn)很多公司開始計劃實施微服務(wù)的時候剩失,往往第一個問題是微服務(wù)應(yīng)該怎么拆屈尼,應(yīng)該拆分到什么粒度册着?覺得是這是一個最重要的一個維度。后來我們發(fā)現(xiàn)其實并不是這個樣子的脾歧,微服務(wù)的拆分只是其中很小的一個方面甲捏,需要匹配一套工具鏈,并且經(jīng)歷十二個過程鞭执,逐步完成司顿。

image
image
image

接下來,我們來解析一個微服務(wù)場景下的問題定位過程兄纺。

image

為什么說在微服務(wù)場景下大溜,我們發(fā)現(xiàn)定位問題的時候,我們會覺得它特別的復(fù)雜估脆,往往需要架構(gòu)師牽頭協(xié)調(diào)各個部門一塊去定位某個問題钦奋。

首先第一個復(fù)雜度就是,從頂層到底層這個層次是實在是太多了疙赠,我們能想到就是任何一個比如說我們發(fā)現(xiàn)請求比較慢的時候付材,我們首先會想到整個層次中,最上面的應(yīng)用是不是出了問題圃阳,應(yīng)用這一層本身就比較復(fù)雜厌衔,圖中密密麻麻的線是double服務(wù)之間的一個調(diào)用關(guān)系,它的復(fù)雜度已經(jīng)十分高了限佩,然后中間一旦出現(xiàn)了慢請求葵诈,這時候其實很難定位到一哪一個點,哪個服務(wù)集群調(diào)用哪個服務(wù)集群祟同。

應(yīng)用層下面這就是容器層,容器下面其實是openstack的云網(wǎng)絡(luò)理疙,我們采取方式是kubernetes和openstack整合的一個方式晕城。因為kubernetes對于容器的發(fā)布,運行十分友好窖贤,對于網(wǎng)絡(luò)尤其是多機(jī)房高可用橫向擴(kuò)展的vpc網(wǎng)絡(luò)特性相對弱一些砖顷,那么正好云在VPC這方面相對比較強(qiáng)一些,例如浮動ip赃梧,跨機(jī)房高科用滤蝠,專線等。容器層或者云網(wǎng)絡(luò)層授嘀,都可能產(chǎn)生問題物咳,例如容器網(wǎng)卡吞吐量受限制,或者ovs吞吐量受限制蹄皱,都會造成性能問題览闰。

再往下是物理網(wǎng)絡(luò)芯肤,因為牽扯到多機(jī)房了,那么可能每機(jī)房還有多高可用區(qū)压鉴,那么整個機(jī)房的拓?fù)浣Y(jié)構(gòu)邏輯也會很復(fù)雜崖咨。

這時候就可以想象說當(dāng)一個服務(wù)的多個副本構(gòu)成一個業(yè)務(wù)集群,當(dāng)從一個業(yè)務(wù)集群到另一個業(yè)務(wù)集群時延高油吭,每個層次都其實都有可能出現(xiàn)問題是吧击蹲?然后我們就需要層層的去排查這個事情。

image

另外一個相對比較頭疼的一個事婉宰,是從前端到后端的層級也是挺多的际邻。問題往往是在壓測的時候會發(fā)現(xiàn),那么壓測的時候芍阎,我們是在我們公有云上去壓真實線上的業(yè)務(wù)世曾,所以其實是走公有網(wǎng)絡(luò)的。

我們可以想象谴咸,從前端到后端經(jīng)歷的環(huán)節(jié)實在是太多了轮听,你比較難判斷他會慢在什么地方。

一開始進(jìn)入機(jī)房岭佳,有邊界路由器血巍,然后有核心匯聚交換機(jī),這是網(wǎng)管部去管的珊随。

接下來就進(jìn)入了虛擬的云網(wǎng)絡(luò)網(wǎng)關(guān)述寡,由云計算部門維護(hù)。

云網(wǎng)關(guān)進(jìn)來后叶洞,會有一層負(fù)載均衡鲫凶,這個負(fù)載均衡是可以適配多機(jī)房的負(fù)載均衡,可以做跨機(jī)房浮動IP漂移衩辟。

再往里面會有個API網(wǎng)關(guān)作為接入層螟炫,然后再往后就是服務(wù)層了。服務(wù)層分業(yè)務(wù)服務(wù)層和基礎(chǔ)服務(wù)層艺晴,之間會引入注冊發(fā)現(xiàn)機(jī)制昼钻,比如說用dubbo管理他們之間的相互調(diào)用。由于微服務(wù)規(guī)模比較大封寞,就像剛才圖中展示的一樣然评,復(fù)雜度很高。

業(yè)務(wù)之間調(diào)用完畢之后狈究,最終肯定是要落庫的碗淌,這時候會涉及到緩存的訪問,緩存后面是數(shù)據(jù)庫。

有時候還涉及到調(diào)用云外的系統(tǒng)贯莺,因而需要經(jīng)過云網(wǎng)絡(luò)的網(wǎng)關(guān)风喇。比如說外部的一些支付系統(tǒng),安全檢測系統(tǒng)缕探,包括大數(shù)據(jù)等魂莫,都是云外的。這兩次網(wǎng)關(guān)其實是不一樣的爹耗,前面網(wǎng)關(guān)是DNAT網(wǎng)關(guān)耙考,后面網(wǎng)關(guān)是SNAT網(wǎng)關(guān)。

可以想象一旦出現(xiàn)性能問題的時候潭兽,經(jīng)過這么多環(huán)節(jié)就比較頭疼倦始,經(jīng)常會困惑,這個問題到底出現(xiàn)在哪個環(huán)節(jié)呢山卦?

image

一般來說鞋邑,性能問題往往通過線上性能壓測發(fā)現(xiàn)的。一般大促之前账蓉,提前一段時間枚碗,就要開始進(jìn)行壓測。壓的時候就會涉及到從前往后铸本,從底到上的所有的系統(tǒng)和部門肮雨,都要派代表去參加,哪一塊出現(xiàn)了問題箱玷,哪一個環(huán)節(jié)出現(xiàn)了性能瓶頸怨规,哪一塊就要改。

線上壓力測試需要有一個性能測試的平臺锡足,做多種形式的壓力測試波丰。例如容量測試,通過梯度的加壓舱污,看到什么時候?qū)嵲诓恍醒教颉C邷y試,測試在最大的限度之上還能承受多大的量扩灯,有一定的余量會保險一些,心里相對比較有底霜瘪。再就是穩(wěn)定性測試珠插,測試峰值的穩(wěn)定性,看這個峰值能夠撐一分鐘颖对,兩分鐘還是30分鐘捻撑。還有秒殺場景測試,限流降級演練測試等。

有的時候壓測會遇到讓人崩潰的事情顾患,例如可能前幾天壓測的時候番捂,看著吞吐量在向好的方向發(fā)展,突然有一天一下子就降下來了江解,這個時候離大促時間越來越近设预,心態(tài)就會比較崩潰,需要大家一塊去看到底是什么問題鹉梨。

image

對于測試環(huán)境的管理扎狱,也是非常關(guān)鍵的闰集。線上壓測的時候,為了讓數(shù)據(jù)和正式的線上數(shù)據(jù)實現(xiàn)隔離宾符,常用的方法是對于消息隊列,緩存灭翔,數(shù)據(jù)庫魏烫,都是使用影子的方式。就需要流量染色的技術(shù)肝箱,帶一個tag進(jìn)去哄褒,說明這個請求是測試數(shù)據(jù),還是真實數(shù)據(jù)狭园。

流量染色的功能读处,除了壓測里面使用,還可以用于測試環(huán)境治理唱矛。在大規(guī)模微服務(wù)場景下罚舱,不可能每個部門部署一套完整的環(huán)境,因為耗費的資源量實在是太大了绎谦。

這時候就需要合理規(guī)劃測試環(huán)境管闷。測試環(huán)境是應(yīng)該和持續(xù)集成的流程緊密協(xié)作的。我們使用分支開發(fā)的方式窃肠,每個功能的開發(fā)在分支上包个,上線的時候,合并到主分支上來冤留,主分支對應(yīng)線上環(huán)境碧囊。

對于測試環(huán)境的規(guī)劃,也是采取類似的思路纤怒。我們會有一個基準(zhǔn)測試環(huán)境糯而,對應(yīng)master分支,里面部署全量的應(yīng)用泊窘。每一個分支熄驼,比如說你修改了五個工程像寒,測試的時候,不需要部署全量的應(yīng)用瓜贾,只需要把這五個工程去創(chuàng)建一個Delta測試環(huán)境就可以了诺祸。當(dāng)客戶端進(jìn)行測試的時候,帶上一個此分支的tag祭芦,從API網(wǎng)關(guān)開始筷笨,微服務(wù)框架嵌入的jar會將這個tag一直帶下去。當(dāng)這五個服務(wù)之內(nèi)相互調(diào)用的時候实束,微服務(wù)框架就會選擇這五個服務(wù)的實例進(jìn)行調(diào)研奥秆,如果需要調(diào)用五個服務(wù)之外的其他服務(wù)的時候,微服務(wù)框架會到master環(huán)境里面咸灿,選擇服務(wù)實例進(jìn)行調(diào)用构订。

有了流量染色的環(huán)境治理機(jī)制,測試環(huán)境數(shù)量就會小小特別多避矢。

image

壓測中一旦出現(xiàn)了慢請求悼瘾,最先從哪里能夠看出來呢。在微服務(wù)的接入層有API網(wǎng)關(guān)這一層审胸。

在API網(wǎng)關(guān)中亥宿,有一個調(diào)用統(tǒng)計功能,可以篩選出慢請求砂沛。在壓測的時候烫扼,每一輪都有一個壓測結(jié)果,是一個列表碍庵,按請求時間排序映企。通過這個列表,可以篩選出這次壓測的時候静浴,最慢的接口都是哪一些堰氓,異常的接口(也即請求響應(yīng)速度有巨大反差)有哪一些? 我們就可以針對于這些接口進(jìn)行特別的排查苹享。

在服務(wù)治理平臺中双絮,服務(wù)之間的調(diào)用也有一個統(tǒng)計,也有個一個排名得问,同樣會列出來哪幾個應(yīng)用需要改進(jìn)囤攀,重構(gòu),或者排查宫纬。

image

和壓測匹配的一個重要的系統(tǒng)是全方位的性能監(jiān)控抚岗。一般的監(jiān)控平臺僅僅會監(jiān)控第一項就是服務(wù)器的性能,比如cpu哪怔,內(nèi)存宣蔚,網(wǎng)卡等。其實監(jiān)控應(yīng)該是全方位的认境,對于應(yīng)用方面的胚委,應(yīng)該監(jiān)控堆的內(nèi)存,GC叉信,線程亩冬,cpu利用率等。業(yè)務(wù)指標(biāo)應(yīng)該監(jiān)控下單數(shù)硼身,支付數(shù)硅急,購物車請求數(shù)等。調(diào)用鏈路監(jiān)控應(yīng)該包括RT值佳遂,TPS等营袜。應(yīng)用組件應(yīng)該監(jiān)控連接的狀態(tài),消息積壓丑罪,zookeeper節(jié)點數(shù)等荚板。還應(yīng)該有一些異常監(jiān)控,例如異常的流量吩屹,Exception跪另,報警等。這些都是在統(tǒng)一的一個平臺上去做的煤搜。

定位問題需要深度的依賴于這個平臺免绿,一般先在這個平臺上去找到大概的問題點,如果不能找到真正原因的話擦盾,就可以更加細(xì)粒度的登到機(jī)器上去看嘲驾。沒有統(tǒng)一的監(jiān)控,會在大規(guī)模微服務(wù)場景下厌衙,有了問題距淫,比較茫然,根本找不到地方婶希。

image

有了統(tǒng)一監(jiān)控平臺榕暇,我們也在壓測的時候,在API網(wǎng)關(guān)上發(fā)現(xiàn)了慢請求喻杈,接下來就需要逐層定位了彤枢。

高延遲的現(xiàn)象往往會先出現(xiàn)在應(yīng)用層,外部的現(xiàn)象就是外部請求的時延高筒饰,如果順著調(diào)用鏈定位下來缴啡,往往會反應(yīng)到內(nèi)部從一個服務(wù)集群到另一個服務(wù)集群的RT值高或者出現(xiàn)大量超時異常。

我們可以查看對于服務(wù)之間相互調(diào)用的監(jiān)控瓷们,dubbo和hystrix我們做了集成业栅,右下角的這個圖是熔斷的基本原理秒咐。通過監(jiān)控我們可以發(fā)現(xiàn)有熔斷的情況出現(xiàn),我們就知道這可能是出現(xiàn)了問題碘裕。

image

一旦出現(xiàn)了問題携取,架構(gòu)部一步一步來分析分析這個問題。我們的排查思路是從上層往下層帮孔,從業(yè)務(wù)層往底層層層排查雷滋,因為如果讓物理網(wǎng)絡(luò)或者虛擬網(wǎng)絡(luò)直接去定位,會比較迷茫文兢。

第一步:先應(yīng)用層初步定位晤斩。

第一件事情,查看近期是否有新變更的發(fā)布上線姆坚,例如昨天壓測的時候還正常澳泵,這次突然出現(xiàn)超時,很可能是新的發(fā)布導(dǎo)致的旷偿。

我們可以重點查看新發(fā)布的應(yīng)用烹俗,甚至可以進(jìn)行代碼review。

如果新發(fā)布的應(yīng)用沒有發(fā)現(xiàn)問題萍程,就需要在整條調(diào)用鏈路上定位問題了幢妄。這個時候應(yīng)用性能監(jiān)控APM可以幫上忙,他可以在整條調(diào)用鏈路里面茫负,找到最耗時的那個環(huán)節(jié)蕉鸳,這是我們應(yīng)該重點定位問題的地方。

image

在最耗時的環(huán)節(jié)上忍法,如果我們發(fā)現(xiàn)TPS比較低潮尝,相應(yīng)時間長,但是CPU使用率不高饿序。

我們可以通過服務(wù)治理平臺勉失,查看這兩個服務(wù)之間的調(diào)用是否開啟了足夠的線程池,當(dāng)前的線程池是否已經(jīng)被打滿原探,如果滿了乱凿,是否可以提高線程池的數(shù)目,這和集群所在的虛擬機(jī)和物理的核的分配是有關(guān)系的咽弦,因為核數(shù)用完了徒蟆,再多的線程徒增調(diào)度成本,沒有收益型型。如果可以提供線程池的數(shù)目段审,可以通過配置中心進(jìn)行統(tǒng)一的配置這個服務(wù)集群的線程池數(shù)目。

很多情況下闹蒜,性能的降低的原因在于數(shù)據(jù)庫層寺枉,這一點在APM上也能看的出來抑淫。這個時候應(yīng)該DBA去查看問題,可以梳理一下SQL語句型凳,通過慢SQL分析丈冬,查看慢的原因,例如索引問題甘畅,死鎖問題等,這些都可以通過Mysql或者DDB的日志找出來往弓。

image

另外一個經(jīng)常出現(xiàn)的問題就是TPS比較低疏唾,但是CPU使用率非常高。

這時候我們需要通過監(jiān)控系統(tǒng)查看線程的狀態(tài)函似,查看耗時的方法列表以及調(diào)用棧槐脏,看哪個線程耗時比較多,是否因為業(yè)務(wù)邏輯的Bug撇寞,是否在一直計算某個東西顿天,或者出現(xiàn)業(yè)務(wù)層的死鎖。

另外就是看是否頻繁的FullGC蔑担,一旦出現(xiàn)了FullGC就會出現(xiàn)一段時間的業(yè)務(wù)邏輯暫停牌废,在大促本來壓力就很大,而且峰值時間比較短的情況下啤握,一個線程hang就會使得調(diào)用鏈擁塞一片鸟缕。我們要通過監(jiān)控系統(tǒng)查看堆的信息,找出耗內(nèi)存的對象排抬,看是否內(nèi)存一直往上漲懂从,是否存在泄露。

另外對于緩存的一個監(jiān)控蹲蒲,應(yīng)用層的緩存設(shè)計一般有多層番甩。我們本來一開始設(shè)計的是有三層緩存的,localcache有兩層届搁,然后分布式緩存有一層缘薛,localcache分主動刷新和被動刷新的兩層,被動刷新就是遇到請求了再刷新咖祭,主動刷新是主動的去過一段時間去刷新掩宜。后來我們又把三層緩存簡化成了兩層緩存,被動刷新的localcache的命中率已經(jīng)足夠用了么翰,再多一層反而會降低性能牺汤。

我們之所以監(jiān)控緩存,是因為我們發(fā)現(xiàn)有時候應(yīng)用層Key使用的不對浩嫌,或者是配置的不對檐迟,會導(dǎo)致緩存層失效补胚,請求就會直接打到數(shù)據(jù)庫,導(dǎo)致請求相對比較的慢追迟。對于緩存的監(jiān)控溶其,我們在緩存的客戶端的jar,會和配置中心進(jìn)行聯(lián)動敦间,監(jiān)控某些我們認(rèn)為相對比較重要的Key瓶逃,當(dāng)Key出現(xiàn)緩存丟失,寫頻繁廓块,或者寫丟失等類似這種事件的時候厢绝,它就會上報到我們的監(jiān)控系統(tǒng)。這個時候带猴,就會發(fā)現(xiàn)導(dǎo)致緩存失效的程序Bug昔汉。

image

第二步:如果應(yīng)用層沒有問題,則檢查異常流量

如果我們確認(rèn)應(yīng)用層的確沒有問題拴清,就需要開始往下層去進(jìn)行懷疑了靶病。

首先第一個比較懷疑的是,是不是出現(xiàn)異常流量口予。比如說有外部的異常流量娄周,可以問問網(wǎng)管和安全部是否網(wǎng)站被DDoS,另外入口網(wǎng)關(guān)是否接受到了大量的請求苹威,例如有臨時的促銷或者臨時的事件昆咽。

如果入口沒有問題,則查看集群的監(jiān)控牙甫,要對照著兩個指標(biāo)看掷酗,一個是服務(wù)端的請求數(shù)目的一個統(tǒng)計,看是否有集中的熱點窟哺,比如說一個集群有多個副本泻轰,其中某個副本收到的請求量特別的大,而其他副本收到的請求數(shù)相對比較低且轨。二是在云主機(jī)里面的網(wǎng)卡虛擬網(wǎng)卡浮声,也是能夠看到相應(yīng)的監(jiān)控的,看是不是網(wǎng)絡(luò)流量就集中到某幾臺機(jī)器上旋奢。這兩個會有一個對照泳挥,如果兩方面指標(biāo)能夠?qū)φ掌饋恚袩狳c比較容易定位至朗,也即請求數(shù)上去了屉符,同時云網(wǎng)絡(luò)的網(wǎng)卡流量也上去了。當(dāng)出現(xiàn)了熱點的時候,就需要通過服務(wù)治理中心或者配置中心矗钟,將請求打散唆香。

如果兩個指標(biāo)不匹配,這時候就有問題了吨艇,也即服務(wù)端請求的數(shù)目其實并沒有多躬它,但是云網(wǎng)絡(luò)發(fā)現(xiàn)出現(xiàn)了問題,這時候就就可能是底層基礎(chǔ)設(shè)施的問題东涡,我們這個例子遇到這個點就是相對比較詭異冯吓,還需要接著解析。

image

如果不是異常流量软啼,就需要從前往后再來梳理這個事桑谍,比如說從核心交換機(jī)到VPC的網(wǎng)關(guān)區(qū)域這些是不是出了問題,這時候就要聯(lián)系機(jī)房的網(wǎng)管部門去定位祸挪,然后是VPC網(wǎng)關(guān)到云的負(fù)載均衡,然后是從負(fù)載均衡到應(yīng)用的API網(wǎng)關(guān)贞间,然后API網(wǎng)關(guān)到應(yīng)用的Controller層贿条,然后是中間的dubbo調(diào)用,然后緩存層到數(shù)據(jù)庫層增热。接下來要按照整個鏈路依次的去排查整以。

image

這里畫了一張經(jīng)比較經(jīng)典的機(jī)房的一個圖,其實任何一家公司機(jī)房的樣子要比這個圖可能要復(fù)雜得多峻仇,這就需要架構(gòu)部門對機(jī)房的架構(gòu)相對比較清楚公黑。

我們會分機(jī)房,分可用區(qū)摄咆,還會分二級可用區(qū)凡蚜,他們會走不同的匯聚交換機(jī),在監(jiān)控系統(tǒng)里面也要標(biāo)明某個服務(wù)器群和另一個服務(wù)集群之間的訪問到底是哪個物理機(jī)集群到哪個物理機(jī)集群之間的訪問吭从,這時候你心里可能需要清楚他們是否在同一個機(jī)架里面朝蜘,或者是在同一個二級可用區(qū),還是在同一個一級可用區(qū)涩金,是跨機(jī)房了谱醇,或者是甚至到異地了,這時候你要心里有個數(shù)步做,因為他們之間的時延都是不一樣的副渴。

image

第二個就是對于VPC網(wǎng)絡(luò)的架構(gòu)是要比較清楚。我們是通過OpenStack Neutron的vxlan去做的這個事情的全度。橫向流量是通過vxlan煮剧,基于OVS去做的,縱向的流量,出去的時候會有網(wǎng)關(guān)轿秧,我們不是用的物理網(wǎng)關(guān)中跌,而是虛擬網(wǎng)關(guān),在數(shù)據(jù)中心里面有一個虛擬網(wǎng)關(guān)的網(wǎng)關(guān)層菇篡,網(wǎng)關(guān)層有的時候是掛在匯聚交換機(jī)下面的漩符,有的機(jī)房要求吞吐量比較大,網(wǎng)關(guān)層可以直接掛在核心交換機(jī)下面的驱还,很可能網(wǎng)絡(luò)瓶頸點會發(fā)生在這些網(wǎng)關(guān)上嗜暴。

image

我們的VPC網(wǎng)絡(luò)是有一定的改進(jìn)的,因為我們要求一個VPC里面能承載的虛擬機(jī)的數(shù)量要比開源的OpenStack要多得多议蟆,能達(dá)到5萬臺的規(guī)模闷沥。

限制網(wǎng)絡(luò)規(guī)模的一是廣播問題,我們可以事先把整個網(wǎng)絡(luò)拓?fù)湎掳l(fā)到一個拓?fù)鋷焐先ジ廊荩恳粋€節(jié)點上的Agent會訂閱拓?fù)鋷斓母率录咛樱瑥亩卤镜氐腛VS策略。每個Agent都會看到整個網(wǎng)絡(luò)的拓樸結(jié)構(gòu)戳粒,則ARP的時候路狮,本地就可以攔截來進(jìn)行返回。

另外的一個改進(jìn)就是虛擬網(wǎng)絡(luò)蔚约,默認(rèn)的虛擬網(wǎng)關(guān)只能做主備奄妨,橫向擴(kuò)展能力沒有這么好,不能夠承載大的并發(fā)量苹祟,這其實需要有一排的虛擬網(wǎng)關(guān)砸抛,全部掛載到匯聚或者核心交換機(jī)上。接下來的問題是縱向的流量怎么從這一排網(wǎng)關(guān)里面去選擇树枫,這里使用了一致性哈希的算法直焙。

image

另外一個改進(jìn)是Kubernetes和OpenStack的整合。左面的圖是Kubernetes默認(rèn)創(chuàng)建一個Pod的流程团赏,好在他是基于事件驅(qū)動的箕般,使得我們可以定制化右面創(chuàng)建Pod的流程。我們開發(fā)了自己的Resource Controller和Scheduler舔清,當(dāng)發(fā)現(xiàn)容器的節(jié)點資源不足的情況下丝里,Controller會調(diào)用IaaS的接口創(chuàng)建云主機(jī),然后加到Kubernetes集群中体谒。這種模式下杯聚,在應(yīng)用層的角度,只能看到容器抒痒,不需要運維Kubernetes幌绍,更加看不到OpenStack的接口,使得應(yīng)用層有統(tǒng)一的編排接口。

image

另外對于容器和Kubernetes層的整合傀广,網(wǎng)絡(luò)層也需要整合颁独,容器也要融合VPC網(wǎng)絡(luò),只有適配了VPC網(wǎng)絡(luò)才能實現(xiàn)多機(jī)房的高可用性伪冰,跨機(jī)房的負(fù)載均衡誓酒,以及跨機(jī)房的浮動IP漂移和切換。比如說一個機(jī)房掛了贮聂,則掛在A機(jī)房的浮動IP地址要能夠切換到B機(jī)房的網(wǎng)關(guān)上去靠柑,并且和核心交換機(jī)有聯(lián)動,路由也要切過來吓懈,這些都只有VPC可以完成這個事情歼冰。

我們開發(fā)了一個自己的CNI插件去做這個事兒,容器沒有使用單獨容器網(wǎng)絡(luò)方案耻警,而是直接用了OVS的網(wǎng)絡(luò)隔嫡,也即OpenStack的OVS是可以直接看到容器的IP地址的,容器的IP地址和虛擬機(jī)的IP是平的甘穿,是屬于同一個局域網(wǎng)畔勤。

這樣其實還有另外一個好處,因為我們還有很多沒有容器化的應(yīng)用扒磁,如果部分做容器化,是可以和容器內(nèi)的應(yīng)用無縫的打通的式曲。一些有狀態(tài)的PaaS也是部署在虛擬機(jī)里面的妨托,也可以實現(xiàn)在同一個局域網(wǎng)內(nèi)的互通。

image

另外一個針對Kubernetes的優(yōu)化就是規(guī)模問題吝羞,這是其中的一個優(yōu)化的例子兰伤。

重啟一個API server的時候會導(dǎo)致一些問題,尤其是在Pod的數(shù)目比較多的時候钧排。通過監(jiān)控圖可以看出敦腔,中間會重啟時間長達(dá)七分鐘,中間出現(xiàn)429錯誤并且飆升恨溜,是因為流控符衔。為什么會流控?因為它重啟的時候糟袁,會有大量的請求重新再連上來判族,由于并發(fā)太多,有可能就把它再沖掛了项戴。

image

那么應(yīng)該如何改進(jìn)呢形帮?方法一就是多級流控,根據(jù)UserAgent, Resource, Verb幾個參數(shù),對于不同的客戶端有不同的流控策略辩撑,比如說對于master上面的進(jìn)程優(yōu)先級相對高一點界斜,對于kubelet結(jié)點上的進(jìn)程,優(yōu)先級就低一些合冀。不會所有的kubelet節(jié)點一股腦上來進(jìn)行注冊各薇。方法二是擁塞控制,Retry-After參數(shù)也即多長時間再重試一次水慨,這個原來是一個默認(rèn)值得糜,我們改成一個動態(tài)的值,根據(jù)系統(tǒng)的繁忙程度是調(diào)節(jié)到1秒到8秒之間晰洒,這樣不同的客戶端重試的時間會錯開朝抖。使得把整個恢復(fù)時間大幅度的降低了,這是我們做的規(guī)牡海化的一個例子治宣。

image

來我們從接入層開始分析。我們在VPC的網(wǎng)關(guān)以及負(fù)載均衡層也是做了優(yōu)化的砌滞。

優(yōu)化之一是基于BGP ECMP的等價路由侮邀,也即對于LB集群和前面的核心交換機(jī)之間配置等價路由,實現(xiàn)橫向擴(kuò)展和負(fù)載均衡贝润。如果使用LVS做這個網(wǎng)關(guān)的話绊茧,可以使用DPDK技術(shù),也即基于DPVS的負(fù)載均衡打掘。

電商請求基本上都是基于HTTPS協(xié)議的华畏,SSL往往通過offload的方式通過硬件進(jìn)行加速,在壓力大的時候尊蚁,優(yōu)化明顯亡笑。

image

對于負(fù)載均衡這一層的問題,出問題的點往往在于虛擬網(wǎng)關(guān)和負(fù)載均衡横朋,

我們要中斷看這一層的網(wǎng)卡是不是丟包仑乌?

另外就是DPDK的PMD進(jìn)程的CPU占用率是不是特別的高,因為默認(rèn)的網(wǎng)卡接收網(wǎng)絡(luò)包是通過中斷通知內(nèi)核來接收包,但是DPDK進(jìn)行了優(yōu)化,它通過主動polling的模式減少中斷宏所,它在用戶態(tài)有一個PMD的進(jìn)程砸烦,他會不斷地從網(wǎng)卡里面去polling,會占用大量CPU,如果他CPU特別高就說明接收包的速度本身就很高了。這時候要注意觀察流量是否存在熱點,流量是否突破單臺瓶頸止剖。

對于虛擬網(wǎng)關(guān)來說腺阳,使用的是一致性哈希的方法選擇網(wǎng)關(guān),隨著持續(xù)的浮動IP的創(chuàng)建和刪除穿香,分布不一定均衡亭引,就算IP分布均衡,這些IP對應(yīng)的業(yè)務(wù)其實沒有那么均衡皮获,例如多個熱點請求落到一個網(wǎng)關(guān)上焙蚓。

如果說是存在熱點,導(dǎo)致DPDK的PMD進(jìn)程CPU過高洒宝,可以采取的策略是高流量的IP地址可以進(jìn)一步地打散购公,重新調(diào)整哈希的策略。

另外會觀察是否超過單臺的瓶頸雁歌,我們會測試每臺機(jī)器的IO的瓶頸宏浩,也會進(jìn)行QoS限流,如果是超過了瓶頸靠瞎,說明這一臺的確壓力過大比庄,如果其他的節(jié)點網(wǎng)絡(luò)IO還相對比較低,基本上也是熱點問題乏盐。如果都高佳窑,則說明需要擴(kuò)容。

另外網(wǎng)關(guān)要注意區(qū)分走哪種類型的網(wǎng)關(guān)父能,通過測試神凑,我們發(fā)現(xiàn)DNAT網(wǎng)關(guān)由于是一對一的,性能比較好何吝。SNAT因為共享IP并且要計算哈希耙厚,還要做conntrack,吞吐量不太容易優(yōu)化上去岔霸。對于功能需求走SNAT網(wǎng)關(guān)比較方便的應(yīng)用,可以建議用戶換成DNAT網(wǎng)關(guān)俯渤,從而獲得高的吞吐量呆细。

image

如果入口流量沒有問題,這時候就要看服務(wù)器之間的調(diào)用是不是有問題八匠,因為我們的容器是套在虛擬機(jī)里面的絮爷,主要起編排和發(fā)布的作用,這時候就要看云主機(jī)的steal是不是特別的高梨树,對于物理機(jī)上的cpu坑夯,多個虛擬機(jī)會競爭排隊,排隊不上就會等待抡四,等待的時候就會出現(xiàn)CPU steal柜蜈,網(wǎng)絡(luò)吞吐量肯定就上不去仗谆,甚至?xí)霈F(xiàn)丟包,因為收到的網(wǎng)絡(luò)包來不及處理淑履。

另外就是磁盤的IO utils是不是有異常隶垮,雖然容器中多部署無狀態(tài)服務(wù),對于磁盤的依賴相對比較小秘噪,日志也是以異步的方式輸出的狸吞,但是有時候也會存在IO hang的情況,這時候就要看IO的監(jiān)控指煎。

如果需要細(xì)致的分析蹋偏,可以登錄到宿主機(jī)上看KVM,分析KVM的性能的瓶頸在哪里至壤,在虛擬機(jī)里面進(jìn)行網(wǎng)絡(luò)監(jiān)控之外威始,在宿主機(jī)上可以對虛擬網(wǎng)絡(luò)的組件進(jìn)行分析,測試兩個集群之間的虛擬網(wǎng)絡(luò)組件是否出現(xiàn)了問題崇渗。

image

分析完了網(wǎng)絡(luò)和存儲虛擬化字逗,接下來看計算虛擬化KVM≌悖可以做一些定制化的一些調(diào)優(yōu)葫掉,比如說CPU的BIOS中會把C-States和P-States這種節(jié)能開關(guān)關(guān)掉,如果是核心業(yè)務(wù)集群跟狱,不需要打開這些開關(guān)俭厚。

另外就是物理CPU和vCPU的綁定,這是為了解決steal的問題驶臊,如果把核綁到虛擬機(jī)上挪挤,基本上就不會存在VCPU在物理CPU之間切換的問題,就會把steal解決掉关翎。

另外是NUMA親和性的問題扛门,在同一個NUMA Node中,CPU對內(nèi)存的訪問就會快一些纵寝,跨NUMA node就會慢一點论寨,分配的時候盡量是同樣CPU和同樣的內(nèi)存放在同一個NUMA 節(jié)點。

虛擬機(jī)網(wǎng)卡可以通過SR-IOV的方式來進(jìn)行優(yōu)化爽茴,云主機(jī)綁定核也是在grub中設(shè)定好葬凳,一臺機(jī)器上面能起多少個服務(wù),給宿主肌留多少核室奏,給監(jiān)控留多少核火焰,然后最后給應(yīng)用留多少核,都是提前規(guī)劃好的胧沫,例如前幾個核是給宿主機(jī)自己去用的昌简,然后幾個核是留給DPDK去用的占业,最后幾個核是留給監(jiān)控去用的,中間的核留給服務(wù)江场。

image

對于限流策略問題纺酸,基礎(chǔ)設(shè)施層和業(yè)務(wù)層有一個配合的問題,底層的網(wǎng)絡(luò)有QoS流控的址否,業(yè)務(wù)其實也有限流的餐蔬,這兩個值要匹配起來,否則會有問題佑附,比如當(dāng)業(yè)務(wù)層把線程數(shù)調(diào)大的時候樊诺,結(jié)果基礎(chǔ)設(shè)施層被限流了會出現(xiàn)丟包。
image

當(dāng)我們從監(jiān)控里面看到有丟包事件的時候音同,業(yè)務(wù)層會懷疑是虛擬網(wǎng)絡(luò)的問題词爬,丟包了以后TCP會重傳,重傳會使得響應(yīng)比較的慢权均。

在沒有定位到到底哪個環(huán)節(jié)丟包的時候顿膨,可以先做如下的處理。為了使TCP的丟包重傳和流控策略不要用默認(rèn)的策略叽赊,也即一旦出現(xiàn)了丟包恋沃,內(nèi)核協(xié)議棧就認(rèn)為網(wǎng)絡(luò)擁塞,從而減少擁塞窗口必指,這時候本來就想加速重傳囊咏,結(jié)果窗口下來了,想加速也加不上去塔橡。如果切換成BBR梅割,出現(xiàn)丟包的時候就會好很多。

但是我們還是就要看底層的網(wǎng)絡(luò)葛家,網(wǎng)絡(luò)包會丟在什么地方户辞。

image

最后實在沒有辦法,就需要登到物理機(jī)上去debug整條鏈路癞谒。從集群A到集群B中間抽出兩臺機(jī)器進(jìn)行測試咆课。測試完畢后通過tcpdump進(jìn)行分析虛擬機(jī)和虛擬機(jī)之間的情況,通過ovs-tcpdump可以分析兩臺物理機(jī)上的OVS之間的情況扯俱,物理機(jī)之間的鏈路可需要進(jìn)行分析。如果包的數(shù)目比較多喇澡,需要寫程序比對時間戳序列號迅栅。

抓包分析之后,我們發(fā)現(xiàn)兩個集群之間并不是任何兩兩個服務(wù)之間都會丟包晴玖,而是發(fā)生在兩個集群全部在某一批匯聚交換機(jī)出現(xiàn)读存。

原來從來沒有懷疑過是物理硬件的問題为流,物理交換機(jī)的監(jiān)控網(wǎng)粒度往往不會非常細(xì),而且有堆疊這種高可用策略让簿,在監(jiān)控調(diào)整到分鐘級別的時候敬察,看流量根本就沒有達(dá)到上限。

但是一旦我們發(fā)現(xiàn)出問題的兩個集群總是要過某一臺匯聚交換機(jī)的時候尔当,我們就建議網(wǎng)管莲祸,你能不能把那臺的監(jiān)控配置到秒級,然后就發(fā)現(xiàn)問題了椭迎,就是分鐘級監(jiān)控沒有超過它的瓶頸锐帜,但是秒級的監(jiān)控就會發(fā)現(xiàn)它瞬時流量是超過了瓶頸的,因而會丟包畜号。原因是部署緩存集群的時候缴阎,實例過于集中了,兩個集群之間的交互基本上都集中在同一個匯聚交換機(jī)上简软,導(dǎo)致出了問題蛮拔,接下來的方式就是把網(wǎng)絡(luò)優(yōu)化型的實例打散了以后,只要流量瞬時不會超過物理交換機(jī)峰值痹升,基本上就沒有問題了建炫。

這個例子最后有一點狗血,其實這是一個分析思路视卢,從應(yīng)用層逐漸的去分析踱卵,架構(gòu)部就要協(xié)調(diào)各個層次,最后才把這個事情定位到好据过,我今天的分享就到這里惋砂。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市绳锅,隨后出現(xiàn)的幾起案子西饵,更是在濱河造成了極大的恐慌,老刑警劉巖鳞芙,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件眷柔,死亡現(xiàn)場離奇詭異,居然都是意外死亡原朝,警方通過查閱死者的電腦和手機(jī)驯嘱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來喳坠,“玉大人鞠评,你說我怎么就攤上這事『攫模” “怎么了剃幌?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵聋涨,是天一觀的道長。 經(jīng)常有香客問我负乡,道長牍白,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任抖棘,我火速辦了婚禮茂腥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘钉答。我一直安慰自己础芍,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布数尿。 她就那樣靜靜地躺著仑性,像睡著了一般。 火紅的嫁衣襯著肌膚如雪右蹦。 梳的紋絲不亂的頭發(fā)上诊杆,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天,我揣著相機(jī)與錄音何陆,去河邊找鬼晨汹。 笑死,一個胖子當(dāng)著我的面吹牛贷盲,可吹牛的內(nèi)容都是我干的淘这。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼巩剖,長吁一口氣:“原來是場噩夢啊……” “哼铝穷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起佳魔,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤曙聂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后鞠鲜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宁脊,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年贤姆,在試婚紗的時候發(fā)現(xiàn)自己被綠了榆苞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡霞捡,死狀恐怖坐漏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤仙畦,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站音婶,受9級特大地震影響慨畸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜衣式,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一寸士、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧碴卧,春花似錦弱卡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至荧飞,卻和暖如春凡人,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背叹阔。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工挠轴, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人耳幢。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓岸晦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親睛藻。 傳聞我的和親對象是個殘疾皇子启上,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容