Consul故障分析與優(yōu)化是怎么樣的

Consul故障分析與優(yōu)化是怎么樣的,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

10年積累的做網(wǎng)站、成都網(wǎng)站設(shè)計經(jīng)驗,可以快速應對客戶對網(wǎng)站的新想法和需求。提供各種問題對應的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務。我雖然不認識你,你也不認識我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有藍田免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

成都創(chuàng)新互聯(lián)公司是工信部頒發(fā)資質(zhì)IDC服務器商,為用戶提供優(yōu)質(zhì)的內(nèi)江服務器托管服務

注冊中心背景及Consul的使用

從微服務平臺的角度出發(fā)希望提供統(tǒng)一的服務注冊中心,讓任何的業(yè)務和團隊只要使用這套基礎(chǔ)設(shè)施,相互發(fā)現(xiàn)只需要協(xié)商好服務名即可;還需要支持業(yè)務做多DC部署和故障切換。由于在擴展性和多DC支持上的良好設(shè)計,我們選擇了Consul,并采用了Consul推薦的架構(gòu),單個DC內(nèi)有Consul  Server和Consul Agent,DC之間是WAN模式并且相互對等,結(jié)構(gòu)如下圖所示:

Consul故障分析與優(yōu)化是怎么樣的

注:圖中只畫了四個DC,實際生產(chǎn)環(huán)境根據(jù)公司機房建設(shè)以及第三方云的接入情況,共有十幾個DC。

與QAE容器應用平臺集成

愛奇藝內(nèi)部的容器應用平臺QAE與Consul進行了集成。由于早期是基于Mesos/Marathon體系開發(fā),沒有Pod容器組概念,無法友好的注入sidecar的容器,因此我們選擇了微服務模式中的第三方注冊模式,即由QAE系統(tǒng)實時向Consul同步注冊信息,如下圖所示;并且使用了Consul的external  service模式,這樣可以避免兩個系統(tǒng)狀態(tài)不一致時引起故障,例如Consul已經(jīng)將節(jié)點或服務實例判定為不健康,但是QAE沒有感知到,也就不會重啟或重新調(diào)度,導致沒有健康實例可用。

Consul故障分析與優(yōu)化是怎么樣的

其中QAE應用與服務的關(guān)系表示例如下:

Consul故障分析與優(yōu)化是怎么樣的

每個QAE應用代表一組容器,應用與服務的映射關(guān)系是松耦合的,根據(jù)應用實際所在的DC將其關(guān)聯(lián)到對應Consul  DC即可,后續(xù)應用容器的更新、擴縮容、失敗重啟等狀態(tài)變化都會實時體現(xiàn)在Consul的注冊數(shù)據(jù)中。

與API網(wǎng)關(guān)集成

微服務平臺API網(wǎng)關(guān)是服務注冊中心最重要的使用方之一。網(wǎng)關(guān)會根據(jù)地區(qū)、運營商等因素部署多個集群,每個網(wǎng)關(guān)集群會根據(jù)內(nèi)網(wǎng)位置對應到一個Consul集群,并且從Consul查詢最近的服務實例,如下圖所示:

Consul故障分析與優(yōu)化是怎么樣的

這里我們使用了Consul的PreparedQuery功能,對所有服務優(yōu)先返回本DC服務實例,如果本DC沒有則根據(jù)DC間RTT由近到遠查詢其它DC數(shù)據(jù)。

故障與分析優(yōu)化

Consul故障

Consul從2016年底上線開始,已經(jīng)穩(wěn)定運行超過三年時間,但是最近我們卻遇到了故障,收到了某個DC多臺Consul  Server不響應請求、大量Consul Agent連不上Server的告警,并且沒有自動恢復。Server端觀察到的現(xiàn)象主要有:

raft協(xié)議不停選舉失敗,無法獲得leader;

HTTP&DNS查詢接口大量超時,觀察到有些超過幾十秒才返回(正常應當是毫秒級別返回);

goroutine快速線性上升,內(nèi)存同步上升,最終觸發(fā)系統(tǒng)OOM;在日志中沒能找到明確的問題,從監(jiān)控metrics則觀察到PreparedQuery的執(zhí)行耗時異常增大,如下圖所示:

Consul故障分析與優(yōu)化是怎么樣的

此時API網(wǎng)關(guān)查詢服務信息也超時失敗,我們將對應的網(wǎng)關(guān)集群切到了其它DC,之后重啟Consul進程,恢復正常。

故障分析

經(jīng)過日志排查,發(fā)現(xiàn)故障前發(fā)生過DC間的網(wǎng)絡(luò)抖動(RTT增加,伴隨丟包),持續(xù)時間大約1分鐘,我們初步分析是DC間網(wǎng)絡(luò)抖動導致正常收到的PreparedQuery請求積壓在Server中無法快速返回,隨著時間積累越來越多,占用的goroutine和內(nèi)存也越來越多,最終導致Server異常。

跟隨這個想法,嘗試在測試環(huán)境復現(xiàn),共有4個DC,單臺Server的PreparedQuery  QPS為1.5K,每個PreparedQuery查詢都會觸發(fā)3次跨DC查詢,然后使用tc-netem工具模擬DC間的RTT增加的情況,得到了以下結(jié)果:

  • 當DC間RTT由正常的2ms變?yōu)?00ms之后,Consul  Server的goroutine、內(nèi)存確實會線性增長,PreparedQuery執(zhí)行耗時也線性增長,如下圖所示:

Consul故障分析與優(yōu)化是怎么樣的

  • 雖然goroutine、內(nèi)存在增長,但是在OOM之前,Consul  Server的其它功能未受影響,Raft協(xié)議工作正常,本DC的數(shù)據(jù)查詢請求也能正常響應;

  • 在DC間RTT恢復到2ms的一瞬間,Consul Server丟失leader,接著Raft不停選舉失敗,無法恢復。

以上操作能夠穩(wěn)定的復現(xiàn)故障,使分析工作有了方向。首先基本證實了goroutine和內(nèi)存的增長是由于PreparedQuery請求積壓導致的,而積壓的原因在初期是網(wǎng)絡(luò)請求阻塞,在網(wǎng)絡(luò)恢復后仍然積壓原因暫時未知,這時整個進程應當是處于異常狀態(tài);那么,為什么網(wǎng)絡(luò)恢復之后Consul反而故障了呢?Raft只有DC內(nèi)網(wǎng)絡(luò)通信,為什么也異常了呢?是最讓我們困惑的問題。

最開始的時候?qū)⒅攸c放在了Raft問題上,通過跟蹤社區(qū)issue,找到了hashicorp/raft#6852,其中描述到我們的版本在高負載、網(wǎng)絡(luò)抖動情況下可能出現(xiàn)raft死鎖,現(xiàn)象與我們十分相似。但是按照issue更新Raft庫以及Consul相關(guān)代碼之后,測試環(huán)境復現(xiàn)時故障依然存在。

之后嘗試給Raft庫添加日志,以便看清楚Raft工作的細節(jié),這次我們發(fā)現(xiàn)Raft成員從進入Candidate狀態(tài),到請求peer節(jié)點為自己投票,日志間隔了10s,而代碼中僅僅是執(zhí)行了一行metrics更新,如下圖所示:

Consul故障分析與優(yōu)化是怎么樣的

因此懷疑metrics調(diào)用出現(xiàn)了阻塞,導致整個系統(tǒng)運行異常,之后我們在發(fā)布歷史中找到了相關(guān)優(yōu)化,低版本的armon/go-metrics在Prometheus實現(xiàn)中采用了全局鎖sync.Mutex,所有metrics更新都需要先獲取這個鎖,而v0.3.3版本改用了sync.Map,每個metric作為字典的一個鍵,只在鍵初始化的時候需要獲取全局鎖,之后不同metric更新值的時候就不存在鎖競爭,相同metric更新時使用sync.Atomic保證原子操作,整體上效率更高。更新對應的依賴庫之后,復現(xiàn)網(wǎng)絡(luò)抖動之后,Consul  Server可以自行恢復正常。

這樣看來的確是由于metrics代碼阻塞,導致了系統(tǒng)整體異常。但我們依然有疑問,復現(xiàn)環(huán)境下單臺Server 的PreparedQuery  QPS為1.5K,而穩(wěn)定的網(wǎng)絡(luò)環(huán)境下單臺Server壓測QPS到2.8K時依然工作正常。也就是說正常情況下原有代碼是滿足性能需求的,只有在故障時出現(xiàn)了性能問題。

接下來的排查陷入了困境,經(jīng)過反復試驗,我們發(fā)現(xiàn)了一個有趣的現(xiàn)象:使用go 1.9編譯的版本(也是生產(chǎn)環(huán)境使用的版本)能復現(xiàn)出故障;同樣的代碼使用go  1.14編譯就無法復現(xiàn)出故障。經(jīng)過仔細查看,我們在go的發(fā)布歷史中找到了以下兩條記錄:

Consul故障分析與優(yōu)化是怎么樣的

根據(jù)代碼我們找到了用戶反饋在go1.9~1.13版本,在大量goroutine同時競爭一個sync.Mutex時,會出現(xiàn)性能急劇下降的情況,這能很好的解釋我們的問題。由于Consul代碼依賴了go  1.9新增的內(nèi)置庫,我們無法用更低的版本編譯,因此我們將go  1.14中sync.Mutex相關(guān)的優(yōu)化去掉,如下圖所示,然后用這個版本的go編譯Consul,果然又可以復現(xiàn)我們的故障了。

Consul故障分析與優(yōu)化是怎么樣的

回顧語言的更新歷史,go  1.9版本添加了公平鎖特性,在原有normal模式上添加了starvation模式,來避免鎖等待的長尾效應。但是normal模式下新的goroutine在運行時有較高的幾率競爭鎖成功,從而免去goroutine的切換,整體效率是較高的;而在starvation模式下,新的goroutine不會直接競爭鎖,而是會把自己排到等待隊列末端,然后休眠等待喚醒,鎖按照等待隊列FIFO分配,獲取到鎖的goroutine被調(diào)度執(zhí)行,這樣會增加goroutine調(diào)度、切換的成本。在go  1.14中針對性能問題進行了改善,在starvation模式下,當goroutine執(zhí)行解鎖操作時,會直接將CPU時間讓給下一個等待鎖的goroutine執(zhí)行,整體上會使得被鎖保護部分的代碼得到加速執(zhí)行。

到此故障的原因就清楚了,首先網(wǎng)絡(luò)抖動,導致大量PreparedQuery請求積壓在Server中,同時也造成了大量的goroutine和內(nèi)存使用;在網(wǎng)絡(luò)恢復之后,積壓的PreparedQuery繼續(xù)執(zhí)行,在我們的復現(xiàn)場景下,積壓的goroutine量會超過150K,這些goroutine在執(zhí)行時都會更新metrics從而去獲取全局的sync.Mutex,此時切換到starvation模式并且性能下降,大量時間都在等待sync.Mutex,請求阻塞超時;除了積壓的goroutine,新的PreparedQuery還在不停接收,獲取鎖時同樣被阻塞,結(jié)果是sync.Mutex保持在starvation模式無法自動恢復;另一方面raft代碼運行會依賴定時器、超時、節(jié)點間消息的及時傳遞與處理,并且這些超時通常是秒、毫秒級別的,但metrics代碼阻塞過久,直接導致時序相關(guān)的邏輯無法正常運行。

接著生產(chǎn)環(huán)境中我們將發(fā)現(xiàn)的問題都進行了更新,升級到go 1.14,armon/go-metrics v0.3.3,以及hashicorp/raft  v1.1.2版本,使Consul達到一個穩(wěn)定狀態(tài)。此外還整理完善了監(jiān)控指標,核心監(jiān)控包括以下維度:

  • 進程:CPU、內(nèi)存、goroutine、連接數(shù)

  • Raft:成員狀態(tài)變動、提交速率、提交耗時、同步心跳、同步延時

  • RPC:連接數(shù)、跨DC請求數(shù)

  • 寫負載:注冊&解注冊速率

  • 讀負載:Catalog/Health/PreparedQuery請求量,執(zhí)行耗時

冗余注冊

根據(jù)Consul的故障期間的故障現(xiàn)象,我們對服務注冊中心的架構(gòu)進行了重新審視。

在Consul的架構(gòu)中,某個DC Consul  Server全部故障了就代表這個DC故障,要靠其它DC來做災備。但是實際情況中,很多不在關(guān)鍵路徑上的服務、SLA要求不是特別高的服務并沒有多DC部署,這時如果所在DC的Consul故障,那么整個服務就會故障。

針對本身并沒有做多DC部署的服務,如果可以在冗余DC注冊,那么單個DC  Consul故障時,其它DC還可以正常發(fā)現(xiàn)。因此我們修改了QAE注冊關(guān)系表,對于本身只有單DC部署的服務,系統(tǒng)自動在其它DC也注冊一份,如下圖所示:

Consul故障分析與優(yōu)化是怎么樣的

QAE這種冗余注冊相當于在上層做了數(shù)據(jù)多寫操作。Consul本身不會在各DC間同步服務注冊數(shù)據(jù),因此直接通過Consul  Agent方式注冊的服務還沒有較好的冗余注冊方法,還是依賴服務本身做好多DC部署。

保障API網(wǎng)關(guān)

目前API網(wǎng)關(guān)的正常工作依賴于Consul PreparedQuery查詢結(jié)果在本地的緩存,目前的交互方式有兩方面問題:

  • 網(wǎng)關(guān)緩存是lazy的,網(wǎng)關(guān)第一次用到時才會從Consul查詢加載,Consul故障時查詢失敗會導致請求轉(zhuǎn)發(fā)失敗;

  • PreparedQuery內(nèi)部可能會涉及多次跨DC查詢,耗時較多,屬于復雜查詢,由于每個網(wǎng)關(guān)節(jié)點需要單獨構(gòu)建緩存,并且緩存有TTL,會導致相同的PreparedQuery查詢執(zhí)行很多次,查詢QPS會隨著網(wǎng)關(guān)集群規(guī)模線性增長。

為了提高網(wǎng)關(guān)查詢Consul的穩(wěn)定性和效率,我們選擇為每個網(wǎng)關(guān)集群部署一個單獨的Consul集群,如下圖所示:

Consul故障分析與優(yōu)化是怎么樣的

圖中紅色的是原有的Consul集群,綠色的是為網(wǎng)關(guān)單獨部署的Consul集群,它只在單DC內(nèi)部工作。我們開發(fā)了Gateway-Consul-Sync組件,它會周期性的從公共Consul集群讀取服務的PreparedQuery查詢結(jié)果,然后寫入到綠色的Consul集群,網(wǎng)關(guān)則直接訪問綠色的Consul進行數(shù)據(jù)查詢。這樣改造之后有以下幾方面好處:

  1. 從支持網(wǎng)關(guān)的角度看,公共集群的負載原來是隨網(wǎng)關(guān)節(jié)點數(shù)線性增長,改造后變成隨服務個數(shù)線性增長,并且單個服務在同步周期內(nèi)只會執(zhí)行一次PreparedQuery查詢,整體負載會降低;

  2. 圖中綠色Consul只供網(wǎng)關(guān)使用,其PreparedQuery執(zhí)行時所有數(shù)據(jù)都在本地,不涉及跨DC查詢,因此復雜度降低,不受跨DC網(wǎng)絡(luò)影響,并且集群整體的讀寫負載更可控,穩(wěn)定性更好;

  3. 當公共集群故障時,Gateway-Consul-Sync無法正常工作,但綠色的Consul仍然可以返回之前同步好的數(shù)據(jù),網(wǎng)關(guān)還可以繼續(xù)工作;

  4. 由于網(wǎng)關(guān)在改造前后查詢Consul的接口和數(shù)據(jù)格式是完全一致的,當圖中綠色Consul集群故障時,可以切回到公共Consul集群,作為一個備用方案。

關(guān)于Consul故障分析與優(yōu)化是怎么樣的問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。

網(wǎng)頁名稱:Consul故障分析與優(yōu)化是怎么樣的
網(wǎng)站URL:http://bm7419.com/article0/phdioo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、網(wǎng)站營銷、網(wǎng)站設(shè)計公司、云服務器網(wǎng)站設(shè)計、Google

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

h5響應式網(wǎng)站建設(shè)