作者:李煌東
?
大家好,我是阿里云的李煌東。今天我為大家分享 Kubernetes 監(jiān)測(cè)公開(kāi)課第四節(jié),如何使用 Kubernetes?監(jiān)測(cè)定位慢調(diào)用。今天的課程主要分為三大部分,首先我會(huì)介紹一下慢調(diào)用的危害以及常見(jiàn)的原因;其次我會(huì)介紹慢調(diào)用的分析方法以及最佳實(shí)踐;最后通過(guò)幾個(gè)案例來(lái)去演示一下慢調(diào)用的分析過(guò)程。
?
慢調(diào)用危害及常見(jiàn)原因
?
?
在開(kāi)發(fā)軟件過(guò)程中,慢調(diào)用是非常常見(jiàn)的異常。慢調(diào)用可能帶來(lái)的危害包括:
?
- 前端業(yè)務(wù)維度:首先慢調(diào)用可能會(huì)引起前端加載慢的問(wèn)題,前端加載慢可能會(huì)進(jìn)一步導(dǎo)致應(yīng)用卸載率高,進(jìn)而影響品牌的口碑。
- 項(xiàng)目交付的維度:由于接口慢導(dǎo)致達(dá)不到 SLO,進(jìn)而導(dǎo)致項(xiàng)目延期。
- 業(yè)務(wù)架構(gòu)穩(wěn)定性:當(dāng)接口調(diào)用慢時(shí),非常容易引起超時(shí),當(dāng)其他業(yè)務(wù)服務(wù)都依賴這個(gè)接口,那么就會(huì)引發(fā)大量重試,進(jìn)而導(dǎo)致資源耗盡,最終導(dǎo)致部分服務(wù)或者整個(gè)服務(wù)不可用的雪崩的現(xiàn)象。
所以,看似一個(gè)無(wú)關(guān)痛癢的慢調(diào)用可能隱藏著巨大風(fēng)險(xiǎn),我們應(yīng)該引起警惕。對(duì)慢調(diào)用最好都不要去忽視它,應(yīng)該盡可能去分析其背后的原因,從而進(jìn)行風(fēng)險(xiǎn)控制。
產(chǎn)生慢調(diào)用的原因有哪些?產(chǎn)生慢調(diào)用的原因是千千萬(wàn)萬(wàn)的,歸結(jié)起來(lái)有五個(gè)常見(jiàn)原因。
- 第一個(gè)是資源使用率過(guò)高問(wèn)題,比如說(shuō) CPU 內(nèi)存、磁盤、網(wǎng)卡等等。當(dāng)這些使用率過(guò)高的時(shí)候,非常容易引起服務(wù)慢。
- 第二個(gè)是代碼設(shè)計(jì)的問(wèn)題,通常來(lái)說(shuō)如果 SQL 它關(guān)聯(lián)了很多表,做了很多表,那么會(huì)非常影響 SQL 執(zhí)行的性能。
- 第三個(gè)是依賴問(wèn)題,服務(wù)自身沒(méi)有問(wèn)題,但調(diào)用下游服務(wù)時(shí)下游返回慢,自身服務(wù)處于等待狀態(tài),也會(huì)導(dǎo)致服務(wù)慢調(diào)用的情況。
- 第四個(gè)是設(shè)計(jì)問(wèn)題,比如說(shuō)海量數(shù)據(jù)的表非常大,億級(jí)別數(shù)據(jù)查詢沒(méi)有分庫(kù)分表,那么就會(huì)非常容易引起慢查詢。類似的情況還有耗時(shí)的操作沒(méi)有做緩存。
- 第五個(gè)是網(wǎng)絡(luò)方面問(wèn)題,比如說(shuō)跨洲調(diào)用,跨洲調(diào)用是物理距離太大了,導(dǎo)致往返時(shí)間比較長(zhǎng),進(jìn)而導(dǎo)致慢調(diào)用?;蛘邇牲c(diǎn)之間的網(wǎng)絡(luò)性能可能比較差。比如說(shuō)有丟包重傳率,重傳率高的問(wèn)題。
今天我們的例子圍繞這五個(gè)方面,我們一起來(lái)看一下。
定位慢調(diào)用一般來(lái)說(shuō)有什么樣的步驟,或者說(shuō)有什么樣的最佳實(shí)踐呢?我這里總結(jié)的為三個(gè)方面:黃金信號(hào) + 資源指標(biāo) + 全局架構(gòu)。?
我們先來(lái)看一下黃金信號(hào)。首先,黃金信號(hào)是出自谷歌 SRE 圣經(jīng)里面的?Site Reliability Engineering?一書。用來(lái)表征系統(tǒng)是否健康的最小指標(biāo)的集合,這其中包括:
- 延時(shí)--用來(lái)描述系統(tǒng)執(zhí)行請(qǐng)求花費(fèi)的時(shí)間。常見(jiàn)指標(biāo)包括平均響應(yīng)時(shí)間,P90/P95/P99 這些分位數(shù),這些指標(biāo)能夠很好的表征這個(gè)系統(tǒng)對(duì)外響應(yīng)的快還是慢,是比較直觀的。
- 流量--用來(lái)表征服務(wù)繁忙程度,典型的指標(biāo)有 QPS、TPS。
- 錯(cuò)誤--也就是我們常見(jiàn)的類似于協(xié)議里 HTTP 協(xié)議里面的 500、400 這些,通常如果錯(cuò)誤很多的話,說(shuō)明可能已經(jīng)出現(xiàn)問(wèn)題了。
- 飽和度--就是資源水位,通常來(lái)說(shuō)接近飽和的服務(wù)比較容易出現(xiàn)問(wèn)題,比如說(shuō)磁盤滿了,導(dǎo)致日志沒(méi)辦法寫入,進(jìn)而導(dǎo)致服務(wù)響應(yīng)。典型的那些資源有 CPU、 內(nèi)存、磁盤、隊(duì)列長(zhǎng)度、連接數(shù)等等。
?除了黃金信號(hào),我們還需要關(guān)注一個(gè)資源指標(biāo)。著名的性能分析大神 Brandan Gregg ,在他的性能分析方法論文章中提到一個(gè) USE 方法。USE 方法是從資源角度進(jìn)行分析,它是對(duì)于每一個(gè)資源去檢查 utilization(使用率),saturation (飽和度),error(錯(cuò)誤) ,合起來(lái)就是 USE 了,檢查這三項(xiàng)基本上能夠解決 80% 的服務(wù)問(wèn)題,而你只需要花費(fèi) 5% 的時(shí)間。?
前面有了黃金信號(hào)、資源指標(biāo)之后,我們還需要關(guān)注什么?正如 Branda 在方法論里面提到的“我們不能只見(jiàn)樹(shù)木,不見(jiàn)森林”。諸葛亮也說(shuō)過(guò)“不謀全局者,不足以謀一域”。我們應(yīng)該把系統(tǒng)架構(gòu)畫出來(lái),從全局去看性能問(wèn)題,而不只是看某個(gè)資源、某個(gè)服務(wù)。把所有東西進(jìn)行綜合考慮,識(shí)別出瓶頸所在,通過(guò)設(shè)計(jì)方法系統(tǒng)性解決問(wèn)題,這也是一種更優(yōu)的方法。所以,我們需要黃金信號(hào)、資源指標(biāo)以及全局架構(gòu)這種組合。
慢調(diào)用最佳實(shí)踐
接下來(lái)我會(huì)講三個(gè)案例,第一個(gè)是節(jié)點(diǎn) CPU 打滿問(wèn)題,這也是典型的資源問(wèn)題導(dǎo)致的服務(wù)慢的問(wèn)題,即服務(wù)自身的資源導(dǎo)致的問(wèn)題。第二個(gè)是依賴的服務(wù)中間件慢調(diào)用的問(wèn)題。第三個(gè)是網(wǎng)絡(luò)性能差。第一個(gè)案例是判斷服務(wù)自身有沒(méi)有問(wèn)題;第二個(gè)案例是判斷下游服務(wù)的問(wèn)題;第三個(gè)就是判斷自身跟服務(wù)之間的網(wǎng)絡(luò)性能問(wèn)題。
我們以一個(gè)電商應(yīng)用舉例。首先流量入口是阿里云 SLB,然后流量進(jìn)入到微服務(wù)體系中,微服務(wù)里面我們通過(guò)網(wǎng)關(guān)去接收所有流量,然后網(wǎng)關(guān)會(huì)把流量打到對(duì)應(yīng)的內(nèi)部服務(wù)里面,比如說(shuō) ProductService、CartService、 PaymentService 這些。下面我們依賴了一些中間件,比如說(shuō) Redis 、MySQL 等等,這整個(gè)架構(gòu)我們會(huì)使用阿里云的 ARMS 的 Kubernetes 監(jiān)測(cè)產(chǎn)品來(lái)去監(jiān)測(cè)整個(gè)架構(gòu)。故障注入方面,我們會(huì)通過(guò) chaosblade 去注入諸如 CPU 打滿、網(wǎng)絡(luò)異常等不同類型的異常。
案例一:節(jié)點(diǎn) CPU 打滿問(wèn)題
節(jié)點(diǎn) CPU 打滿會(huì)帶來(lái)什么樣的問(wèn)題呢?節(jié)點(diǎn) CPU 打滿之后,上面的 Pod 可能沒(méi)辦法申請(qǐng)到更多 CPU,導(dǎo)致里面的線程都處于等待調(diào)度的狀態(tài),進(jìn)而導(dǎo)致慢調(diào)用。除了節(jié)點(diǎn)上面,我們這除了 CPU 之外,還有一些像磁盤、Memory 等等資源。
?接下來(lái)我們看一下 CPU 在 Kubernetes 的集群里面的一些特點(diǎn)。首先,CPU 是可壓縮的資源,在 Kubernetes 里面我們右邊看這些配置,有幾個(gè)常見(jiàn)配置,比如說(shuō) Requests,Requests 是主要是用來(lái)做調(diào)度的。Limits 是用來(lái)去做運(yùn)行時(shí)的一個(gè)限制,超過(guò)這個(gè) Limits,它就會(huì)被限流。所以,我們的實(shí)驗(yàn)原理是說(shuō)對(duì)節(jié)點(diǎn)這個(gè) CPU 進(jìn)行打滿注入,導(dǎo)致 Pod 沒(méi)辦法申請(qǐng)到更多的內(nèi)存,進(jìn)而導(dǎo)致服務(wù)變慢。
在正式開(kāi)始前,我們通過(guò)拓?fù)鋱D對(duì)關(guān)鍵鏈路進(jìn)行識(shí)別,在上面配置一些告警。比如說(shuō)網(wǎng)關(guān)及支付鏈路,我們會(huì)配置平均響應(yīng)時(shí)間 P90 以及慢調(diào)用等告警。然后配置完之后,我這邊會(huì)注入一個(gè)節(jié)點(diǎn) CPU 打滿這么一個(gè)故障。那這個(gè)節(jié)點(diǎn)選的是網(wǎng)關(guān)的節(jié)點(diǎn),大概等待五分鐘之后,我們就可以收到告警,就是第二步里面的那個(gè)驗(yàn)證告警的有效性。
?接下來(lái)我們進(jìn)入根因定位。首先,我們進(jìn)入到查看到網(wǎng)關(guān)的應(yīng)用詳情里面。第一步是查看相關(guān)黃金信號(hào),黃金信號(hào)就是響應(yīng)時(shí)間,我們看到響應(yīng)時(shí)間非常直觀顯示了突增,下面是慢調(diào)用數(shù),慢調(diào)用數(shù)是有一千多個(gè),慢調(diào)用數(shù)突然增多了,P90/P95 出現(xiàn)了明顯上升,并超過(guò)一秒,說(shuō)明整個(gè)服務(wù)也變慢了。?
接下來(lái),我們需要分析資源指標(biāo),在 Pod CPU 使用量圖表中可以看到這段時(shí)間 Pod 使用量上升很快,這個(gè)過(guò)程說(shuō)明需要向宿主機(jī)或者節(jié)點(diǎn)申請(qǐng)更多內(nèi)存。我們進(jìn)一步看一下節(jié)點(diǎn)或者宿主機(jī)的 CPU 使用率是怎么樣的,我們看到這段時(shí)間使用率接近百分之百,Pod 申請(qǐng)不了更多 CPU,進(jìn)一步導(dǎo)致服務(wù)慢了,進(jìn)而導(dǎo)致平均響應(yīng)時(shí)間大量增長(zhǎng)。?
定位到問(wèn)題之后,我們可以想想具體解決方案。通過(guò) CPU 使用率配置彈性伸縮。因?yàn)槲覀儾恢老嚓P(guān)流量或者資源,不知道什么時(shí)候突然就不夠。那么應(yīng)對(duì)這種場(chǎng)景最好的辦法就是給資源配置彈性伸縮,為節(jié)點(diǎn)配置彈性伸縮,主要是為了確保在負(fù)載上升時(shí),資源能夠動(dòng)態(tài)擴(kuò)容。為了給應(yīng)用配置彈性伸縮,我們可以給比如 CPU 指標(biāo),配置一個(gè)增加副本數(shù)的一個(gè)擴(kuò)容動(dòng)作來(lái)去分擔(dān)流量,這里面我們可以配置成最大副本數(shù)為十,最小副本數(shù)為三等等。?
效果如下:注入 CPU 慢故障時(shí),慢調(diào)用會(huì)上升,上升完成之后會(huì)觸發(fā)到彈性伸縮,那就是 CPU 的使用率超過(guò)閾值了,如 70%。那么,它就會(huì)自動(dòng)擴(kuò)出一些副本去分擔(dān)這些流量,我們可以看到慢調(diào)用數(shù)逐步下降直到消失,說(shuō)明我們的那個(gè)彈性伸縮起到作用了。
案例二:依賴的服務(wù)中間件慢調(diào)用的問(wèn)題
接下來(lái)我們看第二個(gè)案例。首先介紹一下準(zhǔn)備工作,左邊這邊圖我們可以看到網(wǎng)關(guān)進(jìn)來(lái)掉了兩個(gè)下游服務(wù),一個(gè)是 MySQL ,一個(gè)是 ProductService,所以在網(wǎng)關(guān)上直接配置一個(gè)大于一秒的告警,平均響應(yīng)時(shí)間 P99 大于一秒的告警。第二步我們看這個(gè) Product 也是在關(guān)鍵鏈路上面,我給它配一個(gè) P99 大于一秒的告警,第三個(gè)是 MySQL ,也配一個(gè)大于一秒的告警,配完之后,我會(huì)在 Product 這個(gè)服務(wù)上面去注入一個(gè) MySQL 慢查詢的故障,大概等到兩分鐘之后,我們就可以看到陸續(xù)告警就觸發(fā)出來(lái)了,網(wǎng)關(guān)跟 Product 上面都有一個(gè)紅點(diǎn)跟一個(gè)灰色的點(diǎn),這一點(diǎn)其實(shí)就是報(bào)出來(lái)的故障,報(bào)出的告警事件,Kubernetes 監(jiān)測(cè)會(huì)把這個(gè)告警事件通過(guò)命名空間應(yīng)用自動(dòng)的 match 到這個(gè)節(jié)點(diǎn)上面,所以能夠一眼的看出哪些服務(wù)、哪些應(yīng)用是異常的,這樣能夠快速定位出問(wèn)題所在。我們現(xiàn)在收到告警了之后,下一步去進(jìn)行一個(gè)根因定位。
首先說(shuō)一下這個(gè)更新定位的流程,告警驅(qū)動(dòng)因?yàn)轭A(yù)防總比補(bǔ)救要好,所以我們是采用先配置告警,再去更新定位這么一個(gè)過(guò)程。然后我們會(huì)用拓?fù)鋪?lái)去進(jìn)行一個(gè)可視化分析,因?yàn)橥負(fù)涫悄軌蛉ミM(jìn)行架構(gòu)感知、分析上下游,可以進(jìn)行可視化分析。當(dāng)收到告警后,可以針對(duì)告警看對(duì)應(yīng)的一個(gè)應(yīng)用發(fā)生了什么情況。第一個(gè)我們看那個(gè)網(wǎng)關(guān),我們看到網(wǎng)關(guān)的那個(gè) P99 上升到 1800 毫秒以上,所以觸發(fā)了一個(gè)大于 1 秒閾值的這么一個(gè)告警。我們可以也可以看到幾個(gè)分位數(shù)都是上漲的,然后我們進(jìn)一步看另外一個(gè)發(fā)生告警的服務(wù),也就是 Product,點(diǎn)開(kāi)這個(gè)節(jié)點(diǎn)之后,我們可以從那個(gè) panel 上面看到這個(gè) Product 也發(fā)生了一個(gè)慢調(diào)用,P99、P95 都已經(jīng)不同程度的發(fā)生慢調(diào)用大都是大于一秒的,然后這時(shí)候我們是可以去看一下 Product 的資源使用情況的,因?yàn)榭赡?Product 本身有問(wèn)題。我們查看 Product 的下游,一個(gè)是 Nacos,一個(gè)是 MySQL,我們看 MySQL 的這個(gè)交互的時(shí)候就發(fā)現(xiàn)這里面有大量的一個(gè)慢調(diào)用,然后看到這些慢調(diào)用之后,點(diǎn)擊這些明細(xì),去下鉆看一下它調(diào)用的時(shí)候發(fā)生了什么事情,我們進(jìn)一步看這些數(shù)據(jù)之后,就會(huì)發(fā)現(xiàn) SQL 里面 Product 調(diào)用 Mysql 的時(shí)候執(zhí)行了一條很復(fù)雜,Join 了多張表的一個(gè) SQL 的語(yǔ)句。從調(diào)用 Trace 看到耗時(shí)非常大,這樣的話我們就能夠定位到基本上是這條 SQL 產(chǎn)生的一個(gè)問(wèn)題了。
?總結(jié)一下我們整個(gè)流程,首先我們會(huì)通過(guò)架構(gòu)感知去識(shí)別關(guān)鍵的路徑,然后在這個(gè)關(guān)鍵路徑上去配置告警去主動(dòng)發(fā)現(xiàn)異常。發(fā)現(xiàn)異常之后,我們通過(guò)應(yīng)用自身的資源指標(biāo)黃金信號(hào)等來(lái)去定位問(wèn)題。如果自身沒(méi)有問(wèn)題,那我們就可往下追蹤下游,我們?nèi)タ聪掠蔚馁Y源指標(biāo),用這么一種方法去定位慢調(diào)用的一個(gè)依賴的問(wèn)題,中間件調(diào)用的問(wèn)題。
案例三:網(wǎng)絡(luò)性能差
接下來(lái)我們講最后一個(gè)例子就是網(wǎng)絡(luò)性能差,Kubernetes?的網(wǎng)絡(luò)架構(gòu)是比較復(fù)雜的,容器之間的通信、Pod 之間的通信、Pod 與服務(wù)之間通信、外部與服務(wù)之間的通信等等。所以復(fù)雜度是比較高的,學(xué)習(xí)的曲線也比較陡峭,這給定位問(wèn)題帶來(lái)一定困難。那么,我們?cè)趺慈?yīng)對(duì)這種情況呢?如果采用關(guān)鍵網(wǎng)絡(luò)環(huán)境指標(biāo)去發(fā)現(xiàn)網(wǎng)絡(luò)異常,有哪些關(guān)鍵環(huán)境指標(biāo)呢?首先一個(gè)是速率跟帶寬,第二個(gè)是吞吐量,第三個(gè)是延時(shí),第四個(gè)是 RTT。?
首先我會(huì)這邊配置一個(gè)告警,注入 MySQL 所在節(jié)點(diǎn)丟包率高這個(gè)故障,等待幾分鐘之后,我們會(huì)收到慢調(diào)用告警,網(wǎng)關(guān)跟 Product 的響應(yīng)時(shí)間都發(fā)生了大于一秒的告警。接下來(lái)我們看一下根因定位,我們看到網(wǎng)關(guān),發(fā)生了慢調(diào)用 P99 的響應(yīng)時(shí)間暴增,然后看 Product 也發(fā)生了平均響應(yīng)時(shí)間突增的問(wèn)題,那就是剛才的服務(wù)慢調(diào)用了,然后我們進(jìn)一步看 Product 的下游,依賴了 Nacos、Redis 、MySQL ?這三個(gè)服務(wù),可以發(fā)現(xiàn)慢調(diào)用是比較明顯的,然后我們查看它的下游時(shí)就發(fā)現(xiàn)了 Product 調(diào) MySQL 的時(shí)候發(fā)生了比較嚴(yán)重的慢調(diào)用,同時(shí)它的 RTT 跟重傳現(xiàn)象也很明顯。?
正常情況下 RTT 是很平穩(wěn)的。它反映的是上下游之間的往返的時(shí)間,如果它都上漲非常快,基本上可以認(rèn)定為它是網(wǎng)絡(luò)問(wèn)題,所以說(shuō)可以看到就是這里面有三條,從網(wǎng)關(guān)、Product、MySQL,從這里我們可以總結(jié)到就是通過(guò)這種識(shí)別關(guān)鍵路徑,然后在拓?fù)渖厦嫒ヅ渲酶婢倪@種方法可以非??斓娜ザㄎ粏?wèn)題,不需要去查證很多散落在各個(gè)地方的信息。我們只需要去在這條拓?fù)渖厦嫒?shù)藤摸瓜的去查看對(duì)應(yīng)的性能指標(biāo),網(wǎng)絡(luò)指標(biāo)等等,快速定位到問(wèn)題所在。所以,這就是我們黃金信號(hào) + 資源指標(biāo) + 資源拓?fù)涠ㄎ幌衤{(diào)用這種異常的最佳實(shí)踐。?
最后總結(jié)下本次最佳實(shí)踐:
1、? 通過(guò)默認(rèn)告警主動(dòng)發(fā)現(xiàn)異常,默認(rèn)告警模板涵蓋 RED,常見(jiàn)資源類型指標(biāo)。除了默認(rèn)下發(fā)的告警規(guī)則,用戶還可以基于模板定制化配置。
2、? 通過(guò)黃金信號(hào)和資源指標(biāo)發(fā)現(xiàn)、定位異常,同時(shí) Trace 配合下鉆定位根因。
3、? 通過(guò)拓?fù)鋱D做上下游分析、依賴分析、架構(gòu)感知,有利于從全局視角審視架構(gòu),從而得到最優(yōu)解,做到持續(xù)改善,構(gòu)建更穩(wěn)定的系統(tǒng)。?
?
點(diǎn)擊??此處??,查看更多可觀測(cè)相關(guān)干貨內(nèi)容與產(chǎn)品實(shí)踐~
?
本節(jié)課的內(nèi)容到這里就結(jié)束了,歡迎大家前往釘釘掃碼或搜索釘釘群(31588365)加入答疑交流群進(jìn)行交流。
?
近期熱門
?
#云原生加速器,為你而來(lái)#
就等你了!趕快點(diǎn)擊??此處??參與報(bào)名吧~
本文摘自 :https://blog.51cto.com/u