什么是監(jiān)控?我認為,對不同的人,這意味著不同的東西。但是,對于這個概念,我們或多或少有一些一致的看法。當有人說監(jiān)控時,我會想到:但顯然,有些人會想到別的事情。這些人顯然是錯的,讓我們繼續(xù)。當我讀了某個白癡寫的一篇 10000 字的博文后,我就不再那么遲鈍了。我把監(jiān)控看作是一個注視你的東西的過程,就像一個保安坐在某處一張堆滿攝像機的桌子前一樣。有時他們會睡著——這是監(jiān)控系統(tǒng)宕機。有時他們會因為甜甜圈送到而分心——這是升級停機。有時攝像機在循環(huán)播放——看著那個畫面,我不知道去哪里,但是可能有人在偷你的東西。還有,你有火警警報器。你不需要人來觸發(fā)它。同樣的道理,當門被打開的時候,那可能連接到警報器上了。也許沒有?;蛘?,警報器 1984 年就壞了。 我知道你是怎么想的。我的觀點是,監(jiān)控任何應用程序與監(jiān)控其他任何東西沒有太大區(qū)別。有些事情你可以自動化。有些事情你做不到。有些東西可以根據(jù)閾值告警。有時你會弄錯這些閾值(尤其是在節(jié)假日)。有時,進一步的自動化設(shè)置不太值得,你只是需要使人更容易看明白。 這里我要討論的是我們所做的事情。每個人的情況都不一樣。什么是重要的,什么是“值得的”,對每個人來說都不相同。就像生活中的其他事情一樣,需要權(quán)衡取舍做出許多決定。以下是我們到目前為止所做的決定。它們不完美。它們還在發(fā)展。當新的數(shù)據(jù)或優(yōu)先事項出現(xiàn)時,我們將在必要時改變先前的決定。這就是大腦的工作原理。 監(jiān)控通常涉及多種數(shù)據(jù)類型,我對其做了如下分類:
讓我們聊下 日志。你幾乎可以記錄任何東西,包括信息消息、錯誤、流量、電子郵件(小心 GDPR)等。 聽起來不錯。我可以記錄任何我想要的東西!有什么需要注意嗎?這是一種權(quán)衡。你是否曾經(jīng)運行過具有大量控制臺輸出的程序?在沒有輸出的情況下運行相同的程序速度更快,不是嗎?日志記錄有一些開銷。首先,通常需要為日志本身分配字符串。這就涉及內(nèi)存和垃圾收集(對于.NET 和其他一些平臺)。當你在某處記錄日志時,這通常意味著磁盤空間。如果我們遍歷一個網(wǎng)絡(luò)(在某種程度上是局部的),這也意味著帶寬和延遲。 剛剛,我只在電子郵件處提到了 GDPR……GDPR 是記錄上述所有數(shù)據(jù)時都要考慮的。記錄的任何東西都要保留并且合規(guī)。這是另外一項需要考慮的成本。 假設(shè)這些都不是大問題,而我們想要記錄所有的東西。好吧,我們就可以擁有太多的好東西。當你需要查看日志時會發(fā)生什么?會需要更多地挖掘。這會使發(fā)現(xiàn)問題變得更加困難和緩慢。對于所有的日志記錄,都是在你認為需要的記錄與最終需要的記錄之間進行權(quán)衡。你會弄錯。一直都會。當出現(xiàn)問題時,你會發(fā)現(xiàn)新添加的特性沒有正確的日志記錄。你最終會明白的(可能在遇到問題之后)…并添加相應的日志。這就是生活。改進并繼續(xù)前進。不要老是想著它,只要吸取教訓并從中學習。以后,你將在代碼評審等方面對此進行更多的思考。 那么我們記錄什么呢?這取決于系統(tǒng)。對于我們構(gòu)建的任何系統(tǒng),我們總是會記錄錯誤。我們使用了 StackExchange.Exceptional,這是我維護的一個開源的.NET 錯誤日志程序。它記錄在 SQL Server 里,可以在應用程序內(nèi)或通過 Opserver 查看(稍后我們將詳細討論)。 對于像 Redis, Elasticsearch 和 SQL Server 這樣的系統(tǒng),我們只是使用它們內(nèi)置的日志記錄和日志輪轉(zhuǎn)機制將日志記錄到本地磁盤。對于其他基于 SNMP 的系統(tǒng),如網(wǎng)絡(luò)設(shè)備,我們將所有這些轉(zhuǎn)發(fā)到 Logstash 集群,通過前端的 Kibana 進行查詢。Bosun 在出現(xiàn)警告時也會查詢上面的許多內(nèi)容,以了解詳細的信息和趨勢,下面我們將深入地討論這些內(nèi)容。 我們也記錄經(jīng)過 HAProxy(我們的負載均衡器)的公共 HTTP 請求的最小摘要(只是頂級…沒有 Cookies、沒有表單數(shù)據(jù)等),因為當有人不能登錄,賬戶合并,或任何其他上百個 Bug 報告進來時,能夠看下是什么導致了他們的問題會非常有價值。我們是在 SQL Server 中通過 聚簇列存儲索引 來實現(xiàn)的。根據(jù)記載,Jarrod Dixon 在大約 8 年前第一次建議并開始了 HTTP 日志記錄,我們那時都說他是個瘋子,這是對資源的巨大浪費。沒有人說他是對的。一種新的按月存儲格式即將推出,但那是另外一個故事了。 在那些請求中,我們使用了 我們很快就會談到的性能分析,并把頭信息和特定的性能數(shù)值一起發(fā)送到 HAProxy。HAProxy 捕獲那些頭信息并拆分成系統(tǒng)日志行,我們會轉(zhuǎn)發(fā)并處理成 SQL。那些頭信息包括:
如果事情變好或變壞,我們可以很容易地查詢并與歷史數(shù)據(jù)進行比較。它還以我們從未想到的方式發(fā)揮作用。例如,當我們查看一個請求和運行中的 SQL 查詢數(shù)量,它能告訴我們用戶沿著代碼路徑走了多遠?;蛘?,當 SQL 連接池請求過多時,我們可以查看在特定時間內(nèi)來自特定服務器的所有請求,看看是什么導致了這種爭用。在這里,我們所做的就是跟蹤 n 個服務的調(diào)用次數(shù)和時間。這超級簡單,但也非常有效。 我們將系統(tǒng)日志監(jiān)聽以及保存成 SQL 的過程稱之為“流量處理服務(Traffic Processing Service)”,因為我們計劃每天發(fā)送報告。 對于每個請求,除了那些頭之外,HAProxy 默認的日志行格式 還有一些其他的時間:
另一個簡單但重要的例子是 Tr 和 AspNetDurationMs 頭(一個計時器會在請求開始時啟動和結(jié)束時停止)之間的增量,它可以告訴我們在操作系統(tǒng)中耗費的時間,在 IIS 中等待線程的時間等等。 健康檢查就是檢查健康狀況?!斑@健康嗎?”,對于這個問題通常有 4 個答案:
按照約定,它們通常分別是綠色、紅色、黃色和灰色。健康檢查有一些一般用法。在任何分布式負載設(shè)置中,如一個服務器集群或一組服務器前的負載均衡器,健康檢查是一種查看成員是否勝任某個角色或任務的方法。例如,在 Elasticsearch 中,如果一個節(jié)點宕機,它將重新平衡分片并在其他成員中加載……當節(jié)點恢復健康時,再次執(zhí)行此操作。在 Web 層,負載均衡器將停止向宕機節(jié)點發(fā)送流量,并繼續(xù)在健康節(jié)點之間進行平衡。 對于 HAProxy,我們使用內(nèi)置的健康檢查,它可以進行健康警告。到 2018 年底,當我寫這篇文章的時候,我們還在使用 ASP.NET MVC5,并且正在向 .NET Core 轉(zhuǎn)換。一個重要的細節(jié)是,我們的錯誤頁面是一個重定向,例如 /questions 到 /error?aspxerrorpath=/questions。這是.NET 舊基礎(chǔ)設(shè)施工作機制的一個實現(xiàn)細節(jié),但當與 HAProxy 結(jié)合時,這成了一個問題。例如,如果你有下面這樣一個請求: server ny-web01 10.x.x.1:80 check 那么,它將收到一個 200-399 之間的 HTTP 狀態(tài)碼響應。(還請記?。核话l(fā)出 HEAD 請求。)400 或 500 將觸發(fā)不健康,但我們的 302 重定向 不會。瀏覽器 在重定向之后將獲得一個 5xx 狀態(tài)代碼,但 HAProxy 不會這樣做。它只做最初的檢查,而一個“健康”的 302 是它所看到的一切。幸運的是,你可以在同一個后端使用 http-check expect 200(或任何狀態(tài)代碼,或范圍,或正則表達式——文檔在 這里)來更改它。這意味著我們的健康檢查端點只允許 200。是的,它不止一次給我們帶來傷害。 不同的應用程序有不同的健康檢查端點,但對于 stackoverflow.com 來說是主頁。我們已經(jīng)討論過幾次要改變這一點,但事實是,主頁檢查了我們可能會檢查不到的東西,而全面檢查很重要。我的意思是,“如果多個用戶點擊同一個頁面,它會發(fā)揮作用嗎?”如果我們對數(shù)據(jù)庫和某些緩存的訪問進行健康檢查,對我們知道需要保持在線的重要內(nèi)容進行一致性檢查,這很好,這比什么都不做要好得多。但是,假設(shè)我們在代碼中放置了一個 Bug,而看似沒有那么重要的緩存未能正確地重新加載,其結(jié)果就是需要為所有用戶渲染頂部狀態(tài)欄。現(xiàn)在,每一頁都遭到了破壞。運行某些代碼的健康檢查路由不會被觸發(fā),但是,加載主視圖的動作可以保證對大量依賴項進行評估,確保它們在進行檢查時可以正常發(fā)揮作用。 我們在庫中也有健康檢查。最簡單的形式就是 心跳),如用 StackExchange.Redis 定期檢查到 Redis 的套接字連接是否活動。我們使用相同的方法來查看套接字是否仍然打開,并且正在被 Stack Overflow 上的 WebSocket 消費者所使用。這是一種不常用的監(jiān)控,但確實用了。 我們還有其他的健康檢查,包括標記引擎服務器。我們可以通過 HAProxy(它會添加一個躍點)來平衡負載,但是,讓每個 Web 層服務器直接知道每個標記服務器對我們來說是一個更好的選項。我們可以 1)選擇如何分配負載,2)更容易地測試新構(gòu)建,3)獲得每個服務器的操作計數(shù)指標和性能數(shù)據(jù)。所有這些都在另一篇文章中介紹,但是對于這個主題:我們有一個簡單的“ping”健康檢查,每秒探測一下標記服務器,從它獲取少量的數(shù)據(jù),比如它最近一次從數(shù)據(jù)庫更新的時間。 所以,就是這樣。你完全可以通過健康檢查來傳達你想要的狀態(tài)。如果它能帶來一些好處,而且開銷是值得的(如你正在運行另一個查詢嗎?),那就試試看吧。微軟的.NET 團隊一直致力于 在 ASP.NET Core 中提供統(tǒng)一的健康檢查方法,但我不確定我們是否會那樣做。我希望我們能提供一些想法,并在我們開始做的時候進行統(tǒng)一……在這個過程中,我們會有更多的想法。 但是,請記住,健康檢查通常會經(jīng)常運行,很經(jīng)常。它們的開銷和可擴展性應該與它們運行的頻率聯(lián)系起來。如果你每 100 毫秒一次、每秒一次、每 5 秒一次或每分鐘檢查一次,那么檢查什么以及評估多少依賴項(并花一些時間檢查……)就非常重要。例如,100 毫秒一次的檢查不能用 200 毫秒。那太過分了。 這里有另外一個需要注意的事項,健康檢查通常可以反映幾個級別的“運行(up)”。一個是“我在這里”,這是最基本的。另一個是“我準備好提供服務了”。后者對于幾乎每個用例都更加重要。但是,對于機器,你不能那樣說,你要用它們喜歡的方式。 在 Stack Overflow,有一個這樣的實際例子:在將 HAProxy 后端服務器從 MAINT(維護模式)切換到 ENABLE 時,我們會假設(shè)后端一直處于運行狀態(tài),直到健康檢查顯示情況并非如此。但是,當從 DRAIN 切換到 ENABLE 時,我們會假設(shè)服務已經(jīng)關(guān)閉,并且必須通過 3 次健康檢查才能獲得流量。當我們處理線程池增長限制和試圖增加的緩存(如 Redis 連接)時,我們可能會由于健康檢查的行為而遇到非常嚴重的線程池饑餓問題。其影響非常大。當我們從耗盡狀態(tài)緩慢地增加時,大約需要 8-20 秒才能完全準備好為新構(gòu)建的 Web 服務器流量提供服務。如果我們從維護狀態(tài)開始,在服務器啟動時,流量會涌入服務器,這個過程需要 2-3 分鐘。健康檢查和流量涌入似乎是很明顯的細節(jié),但它對我們的 部署管道 至關(guān)重要。 我們有一個內(nèi)部工具(同樣是開源的?。┦?httpUnit。它是一個相當易于使用的工具,我們使用它來檢查端點的法規(guī)遵從性。這個 URL 是否返回我們期望的狀態(tài)代碼?來點文本檢查怎么樣?證書有效嗎?(如果無效,我們就無法連接。) 防火墻允許這個規(guī)則嗎? 通過不斷進行這項檢查并在失敗時將其納入警告,我們可以快速地識別問題,特別是從無效配置更改到基礎(chǔ)設(shè)施的問題。在應用用戶負載之前,我們還可以隨時測試新的配置或基礎(chǔ)設(shè)施、防火墻規(guī)則等。要了解更多細節(jié),請參見 GitHub README。 如果我們把視角從數(shù)據(jù)中心移開,我們需要看看是什么在訪問我們。這通常是我們的 CDN 和代理:Fastly。Fastly 有一個 服務 的概念,當你把它看作負載均衡器時,它類似于 HAProxy 后端。Fastly 還內(nèi)置了 健康檢查 功能。在我們的每個數(shù)據(jù)中心中,為了保證冗余,我們都有兩組 ISP。這里,我們可以在 Fastly 中進行配置,優(yōu)化正常運行時間。 比如,NY 數(shù)據(jù)中心目前是我們的主數(shù)據(jù)中心,CO 是我們的備份數(shù)據(jù)中心。在這種情況下,我們希望嘗試:
采用主輔 ISP 的原因與最佳傳輸選項、提交、溢出等有關(guān)。記住這一點,我們就可以在它們之間做出優(yōu)先選擇。通過健康檢查,我們可以非常快速地從 #1 故障轉(zhuǎn)移到 #4。假設(shè)有人在 #1 中切斷了兩個 ISP 的光纖或者 BGP 變得不可靠,那么 #2 會立即啟動。我們可能會在它發(fā)生之前丟棄數(shù)千個請求,但是我們討論的是秒級的事情,用戶僅僅刷新頁面可能就又回到業(yè)務中了。這很完美嗎?不是。這是否比無限期地宕機要好?絕對啊。 我們也使用一些外部健康檢查。監(jiān)控一個全球性服務是很重要的。我們運行正常嗎?Fastly 運行正常嗎?我們在這兒運行正常嗎?我們在那里運行正常嗎?我們在西伯利亞運行正常嗎?誰知道呢?。课覀冇性S多供應商,有大量的節(jié)點,進行監(jiān)控的話需要大量的設(shè)置和配置……或者我們可以給一些人支付少幾個數(shù)量級的錢來把這項工作外包。我們使用 Pingdom 來實現(xiàn)這一點。當事情變糟時,它會提醒我們。 指標是什么?它們可以有幾種形式,但對我們來說,它們是有標記的 時間序列數(shù)據(jù)。簡而言之,這意味著你有一個名稱、一個時間戳、一個值,在我們的情況下,還有一些標記。例如,單條記是下面這個樣子:
記錄中的值也有幾種形式可供采用,但一般情況下是計數(shù)器。計數(shù)器報告一個不斷增長的值(通常在重啟時重置為 0)。通過計數(shù)值隨時間的變化,我們可以求出時間窗口中值的增量。例如,如果 10 分鐘之前的值是 129,389,039,那么我們就知道,服務器上的進程在這 10 分鐘內(nèi)運行了 100 次 0 代垃圾收集。另一個情況是報告一個準確時間點的值,例如“這個 GPU 目前 87°”。那么我們用什么來處理指標呢?稍后我們會講到 Bosun。 好了,我們怎么處理那些數(shù)據(jù)呢?警告!眾所周知,“alert”是由“l(fā)e rat”演變而來的一種變位詞,意思是“向當局發(fā)出尖叫的人”。 這在幾個層次上發(fā)生,我們會為遇到問題的團隊進行定制,以便它們能以最佳的狀態(tài)運行。對于 SRE(站點可靠性工程)團隊,Bosun 是我們內(nèi)部的主要警告源。要詳細了解 Bosun 的警告機制,我建議你觀看 Kyle 在 LISA 的介紹(大約從第 15 分鐘開始)。一般來說,我們在會以下情況下會發(fā)出警告:
還有很多其他的小事情,這些是我一下想到的大類別。 如果有什么問題已經(jīng)夠糟糕了,我們就進入下一個階段:喚醒某人。那是在事情變成真正的問題的時候。它們會直接進入 PagerDuty 并喚醒值班的 SRE。如果那個 SRE 不應答,它將很快升級到另一個 SRE。這種級別的事情有:
既然我們已經(jīng)介紹了所有這些煩人的問題,讓我們深入地研究下工具。 Bosun 是我們用于指標和元數(shù)據(jù)的內(nèi)部數(shù)據(jù)收集工具。它是開源的。沒有什么現(xiàn)成的東西能真正滿足我們對指標和警告的需求,所以我們在大約四年前創(chuàng)建了 Bosun,它給我們提供了極大的幫助。我們可以隨時添加我們想要的任何指標、新功能等等。它具有內(nèi)部系統(tǒng)的所有優(yōu)點,也有所有的成本。我待會再談。它是用 Go 編寫的,這主要是因為絕大多數(shù)指標集都是基于代理的。代理 scollector(主要基于 tcollector 的原則)需要在所有平臺上運行,為此,Go 成為我們的首選。“嘿,尼克,.NET Core 怎么樣?”也許可以,但還不夠。不過,這個故事越來越有吸引力了?,F(xiàn)在,我們可以很容易地部署單個可執(zhí)行文件,而 Go 還是領(lǐng)先的。 Bosun 后臺使用 OpenTSDB 進行存儲。它是一個構(gòu)建在 HBase 之上的 時間序列數(shù)據(jù)庫,具有很高的可伸縮性。至少人們是這么告訴我們的。在 Stack Exchange/Stack Overflow,我們遇到的問題通常來自效率和吞吐量方面。我們使用少量硬件做了很多事情。在某些方面,這令人印象深刻,我們?yōu)榇烁械阶院?。另一方面,對于那些設(shè)計運行方式不同的東西,它會產(chǎn)生扭曲和破壞。對于 OpenTSDB 的情況,從空間的角度來看,我們不需要很多硬件來運行它,但是 HBase 的設(shè)計方式使得我們必須給它配置更多的硬件(特別是在網(wǎng)絡(luò)前端)。當處理的數(shù)據(jù)量比較少時,有一個 HBase 復制問題,我在這里不想深入討論這個問題,因為這本身就是一篇文章了,而且是一篇很長的文章。 這是一件麻煩事,花費了我們大量的金錢,以至于我們試圖使用 SQL Server 聚簇列存儲索引作為 Bosun 的后臺。我們已經(jīng)實現(xiàn)了這一點,但對于某些基數(shù)的查詢并沒有產(chǎn)生非常顯著的效果,并且會導致 CPU 使用率很高。Nexus 交換核心指標數(shù)據(jù)占用的總帶寬比大多數(shù)其他指標加起來還多出 400 倍,像這樣的事情并不可怕。大多數(shù)東西運行良好。在一臺像樣的服務器上,每秒記錄 50-100k 的指標數(shù)據(jù)只需要大約 5% 的 CPU——這不是問題。某些查詢是痛點,我們還沒有回到那個問題上……這是一個“可能”的問題,我們是否能解決它,需要多少時間。不管怎樣,這也是另一篇文章。 對于使用.NET 的情況,我們使用 BosunReporter 發(fā)送指標,這是我們維護的另一個開源 NuGet 庫。它看起來是下面這個樣子:
差不多就是這樣。我們現(xiàn)在有了一個流入 Bosun 的數(shù)據(jù)計數(shù)器。我們可以添加更多的標記——例如,我們把它正在哪個服務器上發(fā)生(通過主機標記)包含進去,此外,我們還可以在 IIS 中添加應用程序池,或者供用戶訪問的問答站點等等。更多細節(jié)請查閱 BosunReporter README。很好玩。 許多其他的系統(tǒng)也可以發(fā)送指標,scollector 為 Redis、Windows、Linux 等提供了 大量的內(nèi)置收集器。我們用于關(guān)鍵監(jiān)控的另一個外部實例是一個小型 Go 服務,它可以監(jiān)聽 Fastly 實時日志流。有時候,F(xiàn)astly 可能會返回 503,因為它無法到達我們,或者因為其他什么原因,誰知道呢?我們和它們之間的任何東西都可能出錯??赡苁潜磺袛嗟奶捉幼郑蛘呤锹酚蓡栴},或者是無效的證書。無論原因是什么,我們都希望在這些請求失敗且用戶感覺到的時候發(fā)出警告。這個小服務只監(jiān)聽日志流,從每個條目中解析出一些信息,然后將聚合指標發(fā)送給 Bosun。目前,這還不是開源的,因為我不確定我們是否提到過它的存在。如果需要這樣的東西,告訴我們,我們會考慮一下。 我非常喜歡 Bosun 的一個關(guān)鍵特性,它能夠在設(shè)計時利用歷史數(shù)據(jù)測試警告。這有助于了解它將在何時被觸發(fā)。這是一項很棒的完整性檢查。老實說,監(jiān)控并不完美,它從來都不完美,也永遠不會完美。很多監(jiān)控都是從經(jīng)驗教訓中學來的,因為出錯的事情通常包括你從未想過會出錯的事情……這意味著你沒有從第一天起就監(jiān)控和 / 或警告。警告通常是在出錯后添加的。盡管你非常用心,進行了周密的計劃,你還是會漏掉一些事情,并且在第一次事件之后添加警告。沒關(guān)系。那是過去的事了。你現(xiàn)在所能做的就是把事情做得更好,希望這種情況不會再發(fā)生。不管你是提前設(shè)計還是事后回想,這個功能都很棒:你可以看到,11 月 18 日有一個系統(tǒng)慢到足以觸發(fā)警告,但其他的都是綠色的。在任何人得到通知之前,通過完整性檢查確認警告是否是噪聲?我喜歡這個特性。 然后我們有嚴重的錯誤,這些錯誤非常緊急,需要盡快解決。對于這些情況,我們會將它們發(fā)布到我們的內(nèi)部聊天室。像 創(chuàng)建 Stack Overflow 團隊 出現(xiàn)錯誤,或者計劃任務失敗了,就屬于這樣的情況。我們還有指標通過以下幾種方式監(jiān)控(通過 Bosun)錯誤:
如果我們在上述兩種情況中的任意一種情況下發(fā)現(xiàn)了高錯誤率,那么一兩分鐘后,帶有詳細信息的消息就會出現(xiàn)在聊天中。(由于它們是基于聚合計數(shù)的,因此不能立即警告。)這些帶有鏈接的消息讓我們可以快速深入地研究這個問題。網(wǎng)絡(luò)出現(xiàn)了問題嗎?我們和 Fastly(我們的代理和 CDN)之間是否存在路由問題?是不是有一些糟糕的代碼出了問題?有人踢到電源線了嗎?是不是有人把兩個入電器都插到同一個出現(xiàn)故障的 UPS 上了?所有這些都非常重要,我們希望盡快地進行深入研究。 另一種傳遞警告的方式是電子郵件。Bosun 有一些很好的功能可以幫助我們。電子郵件可能只是一個簡單的警告。比方說,磁盤空間正在減少,或者 CPU 處于高位,而電子郵件中的一個簡單圖表就能說明很多問題……然后我們會有更復雜的警告。比如說,我們更改了共享錯誤存儲中允許的錯誤閾值。很好,我們收到警告了!但是…是哪款應用呢?這是一次性的峰值嗎?正在發(fā)生嗎?這時,定義從 SQL 或 Elasticsearch 中查詢更多數(shù)據(jù)的查詢的能力就非常有用了(還記得所有那些日志記錄嗎?)我們可以在電子郵件中添加故障和詳細信息。你可以更好地處理(甚至決定忽略)電子郵件警告,而無需進一步研究。下面是幾天前 NY-TSDB03 的 CPU 突發(fā)事件的郵件示例:我們也包括了在這個有問題的系統(tǒng)上發(fā)生的與這個警告相關(guān)的最近 10 個事件,所以你可以很容易地識別一個模式,看看它們?yōu)槭裁幢缓雎裕鹊?。它們沒有出現(xiàn)在這封被我用作示例的電子郵件中。 好的,警告很好,但我想看一些數(shù)據(jù)。畢竟,如果你看不到這些數(shù)據(jù),那它們又有什么用呢?展示和可訪問性很重要。能夠快速地消費數(shù)據(jù)是很重要的。時間序列數(shù)據(jù)的圖形可視化是一種很好的探索方法。當涉及到監(jiān)控時,你必須(1)查看數(shù)據(jù),或者(2)擁有非??煽康?100% 的警告覆蓋率,這樣就沒有人需要查看數(shù)據(jù)。第二條是不可能的。當發(fā)現(xiàn)問題時,通常需要反過來查看問題是何時開始的?!拔覀冊趺磧蓚€星期了都沒有注意到這一點?!”這種情況并不像你想象的那么罕見。所以,歷史視圖是有幫助的。 我們在這里使用了 Grafana。這是一款優(yōu)秀的開源工具,我們?yōu)樗峁┝艘粋€ Bosun 插件,這樣,它就可以作為一個數(shù)據(jù)源。(從技術(shù)上講,你可以直接使用 OpenTSDB,但這個可以增強功能。)關(guān)于 Crafana 的使用,我將依次用一些圖片進行說明。 下面一個狀態(tài)儀表板,顯示 Fastly 的運行情況。因為我們借助它們實現(xiàn) DDoS 保護和更快的內(nèi)容交付,所以它們的當前狀態(tài)在很大程度上也是我們的當前狀態(tài)。這只是任意一個我覺得很酷的儀表板。這是按來源國家劃分的流量。它被分成了幾個主要的大洲,你可以看到,當人們醒著的時候,流量是如何在世界各地周而復始地波動的。如果你在 Twitter 上關(guān)注我了,你可能會注意到 .NET Core 存在一些垃圾收集問題。不過,需要對這一點進行關(guān)注并不是一個新需求。下面這個儀表板我們已經(jīng)使用很多年了:注意:不要用上面的數(shù)字來做任何規(guī)模的衡量,這些截圖是在假日周末拍攝的。 請注意,上面提到的所有內(nèi)容都是服務器端的。你到現(xiàn)在還在考慮上面的內(nèi)容嗎?如果你是這樣做的,那就太棒了。很多人直到這成為問題時才會進行這樣的思考。但這一直都很重要。 重要的是要記住,你渲染網(wǎng)頁的速度并不重要。唯一重要的是用戶認為你的網(wǎng)站有多快。感覺有多快?這體現(xiàn)在客戶體驗的許多方面,從最初的頁面繪制到內(nèi)容閃爍(請不要閃爍或移動?。?、廣告呈現(xiàn)等等。 這里要考慮的因素有,例如,以下動作花了多長時間:
這些對用戶體驗很重要。我們的問題頁渲染在 18 毫秒以內(nèi)。我覺得這太棒了。我甚至可能有偏見。但是,對于用戶來說,如果要花很長時間才能打開,那么這就是廢話。 那么,我們能做些什么呢?幾年前,我根據(jù)我們的需要倉促構(gòu)建了一個可以在瀏覽器中使用的客戶端計時管道。其理念很簡單:使用 Web 瀏覽器提供的 導航計時 API 并記錄時間。就是這樣。還有一些完整性檢查(你不會相信 NTP 時鐘校正的數(shù)值,在渲染期間,它會從同步中產(chǎn)生無效的計時,導致時鐘倒退)。對于 Stack Overflow(或我們網(wǎng)絡(luò)中的任何問答站點)5% 的請求,我們會請求瀏覽器發(fā)送這些計時。我們可以隨意調(diào)整這個百分比。 要了解其工作原理,請訪問 teststackoverflow.com。下面是一個示例:準確地講,這并不是監(jiān)控,但有點像。我們使用它來測試一些事情,比如,當我們 切換到 HTTPS 時,連接時間在世界范圍內(nèi)對每個人的影響(這就是我最初創(chuàng)建計時管道的原因)。當我們 添加 DNS 提供商 時也使用了它,在經(jīng)歷過 2016 年的 Dyn DNS 攻擊 之后,我們現(xiàn)在已經(jīng)有了多個提供商。 現(xiàn)在,我們有了一些數(shù)據(jù)。如果我們從 5% 的流量中獲得了這些數(shù)據(jù),將其發(fā)送到服務器,放入 SQL Server 中一個龐大的聚簇列存儲中,并在此過程中把部分指標發(fā)送到 Bosun,那么我們就得到了一些有用的東西。我們可以在配置前后進行測試,查看數(shù)據(jù)。我們也可以關(guān)注當前的流量狀況并查找問題。在最后一部分,我們使用了 Grafana,如下圖所示:注意:這是一個 95 百分位視圖,總渲染時間的中值是靠近底部的白點(大多數(shù)時間小于 500 毫秒)。 有時候,你希望捕獲的數(shù)據(jù)比上面的場景更具體也更詳細。在我們的情況下,我們在大約十年前就決定,我們想知道網(wǎng)頁渲染每一個頁面視圖需要多長時間。對于任何東西,監(jiān)控和查看同樣重要。一個比較好的實現(xiàn)方法是,使它在你查看的每一個頁面視圖上都可見。于是,MiniProfiler 誕生了。它有幾種版本(項目略有不同):.NET、Ruby、Go和 Node.js。我們在這里將看下我維護的.NET 版本:在默認情況下,這是你能看到的所有數(shù)值,但是你可以展開它,以樹的形式查看什么事情花費了多長時間。你可以點擊到那里的連接,快速查看正在運行的 SQL 或 Elastic 查詢,或發(fā)起的 HTTP 調(diào)用,或獲取的 Redis 鍵等等,如下圖所示:注意:如果你正在想,這比我們所說的問題平均渲染耗時(甚至是第 99 百分點)要長得多。是的,這是因為我在這里多加載了很多東西。 由于 MiniProfiler 的開銷非常小,所以我們可以在每個請求上運行它。為此,我們在 Redis 中保留了每個 MVC 路由的性能分析樣本。例如,對于任何路由,我們會保留給定時間內(nèi)最慢的 100 條性能分析樣本。這讓我們能夠看到哪些用戶可能會點擊我們沒有點擊的內(nèi)容?;蛘?,可能有匿名用戶使用了不同的查詢,而這個查詢很慢……我們需要能夠看到這些。我們可以看到 Bosun 中變慢的路由,HAProxy 日志中的點擊率,以及需要深入研究的性能分析快照。所有這些都不需要查看任何代碼,這是一個強大的概覽組合。MiniProfiler 非常棒,但在這里,它也是一個更大的工具集的一部分。 以下是快照和聚合匯總示例:我們或許應該在庫中加入一個這樣的例子。我會盡快抽出時間來做這件事的。 MiniProfiler 由 Marc Gravell、Sam Saffron 和 Jarrod Dixon 創(chuàng)建。從版本 4.x 開始,我成了主要的維護者,但這些先生會對它的存在負責。我們在所有的應用程序中都使用了 MiniProfiler。 注意:看到截圖中的那些 GUID 了嗎?這是 MiniProfiler 生成的一個 ID,我們現(xiàn)在用它作為“請求 ID”,我們會把它記錄到 HAProxy 日志中,對于任何異常,亦是如此。像這樣的小東西有助于把世界聯(lián)系在一起,讓你更容易把事情聯(lián)系起來。 那么,Opserver 是什么?這是一個基于 Web 的儀表板和監(jiān)控工具,這是我在 SQL Server 的內(nèi)置監(jiān)控欺騙了我們之后開始創(chuàng)建的。大約 5 年前,我們遇到了一個問題,SQL Server AlwaysOn 可用性組在 SSMS 儀表板上顯示為綠色(基于主服務器),但是副本已經(jīng)好幾天沒有新數(shù)據(jù)了。這是一個監(jiān)控出現(xiàn)嚴重問題的例子。當時的情況是 HADR 線程池耗盡,并停止更新處于“一切正常(all good)”狀態(tài)的視圖。這樣的設(shè)計不一定是缺陷,但是當緩存 / 存儲一個事物的狀態(tài)時,需要有一個時間戳。如果它在 從那時起,我就針對其他我們想在一個基于 Web 的快速視圖中查看的系統(tǒng)添加了監(jiān)控。我們可以看到所有服務器(基于 Bosun、Orion 或直接基于 WMI)。以下是 Opserver 現(xiàn)狀的概要介紹。 首頁儀表板是一個服務器列表,顯示了什么在運行。用戶可以根據(jù)名稱、服務標記、IP 地址、VM 主機等進行搜索。你還可以下鉆,查看每個節(jié)點上 CPU、內(nèi)存和網(wǎng)絡(luò)的全時歷史圖。節(jié)點如下所示:如果使用 Bosun,并運行 Dell 服務器,那么我們會像下面這樣添加硬件元數(shù)據(jù): 在 SQL Server 儀表板中,我們可以看到所有服務器的狀態(tài)以及可用性組的運行情況。在任何給定的時間,我們可以看到每個節(jié)點有多少活動以及哪個是主節(jié)點(藍色部分)。下面的部分是 AlwaysOn 可用性組,我們可以看到每個組的主節(jié)點是哪臺服務器,副本滯后多少,以及備份了多少隊列。如果事情變糟,一個副本不健康,就會出現(xiàn)更多的指示器,比如,顯示哪些數(shù)據(jù)庫有問題,主服務器上所有與 T-logs 相關(guān)的驅(qū)動器的空閑磁盤空間(因為如果副本繼續(xù)宕機,它們將開始增長):還有一個頂級的“所有作業(yè)(all-jobs)”視圖,可以用于快速監(jiān)控以及啟用 / 停用:在單實例視圖中,我們可以看到該服務器的統(tǒng)計信息、緩存等,這些是我們隨著時間推移發(fā)現(xiàn)的比較重要的指標。對于每個實例,我們還會報告頂級查詢(基于計劃緩存,而不是查詢存儲)、當前活動的查詢(基于 sp_whoisactive)、連接和數(shù)據(jù)庫信息。如果你想下鉆查看一個頂級查詢的詳細信息,則可以看到類似下圖所示的內(nèi)容:在數(shù)據(jù)庫視圖中,可以下鉆查看表、索引、視圖、存儲過程和存儲使用情況等信息。 對于 Redis,我們希望看到主節(jié)點和副本節(jié)點組成的拓撲鏈以及每個實例的總體狀態(tài)。請注意,你可以終止客戶端連接、獲取活動配置、更改服務器拓撲并分析每個數(shù)據(jù)庫中的數(shù)據(jù)(通過 Regexes 進行配置)。最后一個是重量級的 KEYS 和 DEBUG OBJECT 掃描,因此,我們在副本節(jié)點上運行它,或者可以強制在主節(jié)點上運行它(為了安全起見)。下面是一個分析結(jié)果示例: 對于 Elasticsearch,我們通常希望在一個集群視圖中進行查看,因為那是它的行為方式。下圖中沒有索引變?yōu)辄S色或紅色。當這種情況發(fā)生時,儀表板會新增一部分顯示有問題的分片、它們正在做什么(初始化、重定位等),以及在每個集群中出現(xiàn)的次數(shù),匯總顯示有多少分片處于哪種狀態(tài)。注意:上面的 PagerDuty 選項卡從 PagerDuty API 中提取數(shù)據(jù)并顯值班信息,以誰為主,以誰為輔,你可以查看和聲明事件,等等。(這部分數(shù)據(jù)不便于分享,所以這里沒有提供截圖)它還有一個可配置的原始 HTML 部分,向訪問者提供關(guān)于做什么或聯(lián)系誰的說明。 Opserver 中的異常是基于 StackExchange.Exceptional 的。在這一部分,我們將特別關(guān)注 SQL Server 存儲提供程序。對于許多應用程序來說,Opserver 是一種共享單個數(shù)據(jù)庫和表布局并讓開發(fā)人員在一個地方查看其異常的方法。這里的頂層視圖可以是應用程序(默認),也可以在組中配置。在上面的例子中,我們按團隊配置應用程序組,這樣團隊就可以標記或快速點擊他們負責的異常。在每個異常的頁面中,可以看到如下詳細信息:其中還記錄了其他一些細節(jié),比如請求頭(有安全過濾器,因此我們不記錄身份驗證 Cookie)、查詢參數(shù)和添加到異常中的任何其他自定義數(shù)據(jù)。 注意:你可以配置多個存儲,例如,我們上面就配置了 New York 和 Colorado。這些是獨立的數(shù)據(jù)庫,允許所有應用程序登錄到一個非??拷镜氐拇鎯?,并且仍然可以從一個儀表板訪問它們。 HAProxy 部分非常簡單—我們只是顯示 HAProxy 的當前狀態(tài)并允許對其進行控制。主儀表板如下所示:對于每個后臺組、特定的后端服務器、整個服務器或整個層,它也允許一些控制。我們可以把一個后端服務器踢出輪轉(zhuǎn),或者讓整個后端停止運行,或者,如果需要的話,我們還可以把一個 Web 服務器從所有后端中剔除,從而關(guān)閉它進行緊急維護,等等。 關(guān)于 Opserver,人們經(jīng)常問我同樣的問題,以下是對其中一部分問題的回答:
注意:Opserver 目前正在被移植到 ASP.NET Core,因為我晚上有時間。這將使它可以在沒有 IIS 的情況下運行,并有望很快在其他平臺上運行。有些東西,比如從 Linux 上進行 SQL 服務器的 AD 身份驗證,仍然有待解決。如果你希望部署 Opserver,請注意,部署和配置將發(fā)生巨大的變化(會更簡單),所以你最好等一段時間。 監(jiān)控是一個不斷發(fā)展的東西。我想,對每個人來說都是這樣。但是,我只能介紹下我參與的計劃,那么,我們下一步有什么打算呢? 對于健康檢查的改進,我已經(jīng)考慮了一段時間了,但還沒能抽出時間。你在監(jiān)控什么東西時,真相的來源是一個值得關(guān)注的點。有兩個問題,一個是這個東西是什么,另一個是這個東西應該是什么。后者由誰定義?我認為,我們可以在依賴方面做一些改進,讓它的適應面更廣(我真的希望有人已經(jīng)在做類似的事情,如果是這樣,請告訴我?。┤绻覀儚慕】禉z查中得出一個類似下面這樣的簡單結(jié)構(gòu)會怎樣? public class HealthResult 這只是我的想法,但關(guān)鍵是 Dependencies。如果你問 Web 服務器,“嘿,伙計,最近怎么樣?”它返回的不是一個簡單的 JSON 對象,而是由它們構(gòu)成的樹?但是,每一層都是一樣的,所以總的來說,我們有一個遞歸的依賴項列表。例如,一個包含 Redis 的依賴項列表——如果我們無法到達 2 個 Redis 節(jié)點中的 1 個,我們在列表中將有 2 個依賴項,一個的狀態(tài)是 Healthy,另一個的是 Critical 或 Unknown,而 Web 服務器的狀態(tài)是 Warning 而不是 Healthy。 這里的要點是:監(jiān)控系統(tǒng)不需要知道依賴關(guān)系。系統(tǒng)本身定義并返回它們。這樣,我們就不會陷入配置偏離,即被監(jiān)控的東西與應該存在的東西不匹配。這通常發(fā)生在拓撲或依賴關(guān)系有變化的部署中。 這可能是一個糟糕的想法,但對于 Opserver(或任何腳本)來說,要獲得健康讀數(shù)以及健康讀數(shù)的原因,這是一個很一般的想法。如果我們失去了另一個節(jié)點,就會有 n 個東西被破壞?;蛘撸覀兛吹?n 個健康警告的共同原因。通過指向一些端點,我們可以得到所有事物的樹形視圖。你需要為自己的用例添加更多的數(shù)據(jù)嗎?當然!它是 JSON,因此,只需要從對象繼承并根據(jù)需要添加更多內(nèi)容即可。這是一個很容易擴展的模型。我需要花點時間來做這個,也許它會有很多問題?;蛘咦x到這篇文章的人會告訴我,這已經(jīng)完成了。 由于沒有資源和其他需要優(yōu)先處理的事項,Bosun 在很大程度上處于維護狀態(tài)。我們沒有做我們想的那么多,因為我們需要就最佳的前進道路進行討論。是否有其他工具彌補了最初導致我們構(gòu)建它的缺陷?SQL 2017 或 2019 是否已經(jīng)大大改善了我們遇到問題的查詢?我們需要花些時間對生態(tài)圈做些考察,評估一下我們想做的東西。這是我們想在 2019 年第一季度開展的工作。 我們知道自己想要做一些事情,例如改進警告編輯體驗以及 UI 的其他一些方面。我們只是需要權(quán)衡一些事情,弄清楚我們的時間用在什么地方最好。 我們的應用程序?qū)χ笜说睦眠€相當?shù)夭怀浞?。我們知道這一點。這個系統(tǒng)主要是為 SRE 和開發(fā)人員構(gòu)建的,但是,在向開發(fā)人員展示指標的所有優(yōu)點和強大之處(包括指標多么容易添加)方面,我們做得不夠好。我們在上個月的公司聚會上討論過這個話題。添加指標的代價是如此之低,我們可以做得更好。對此,有各種不同的觀點,但我認為,這主要是一個我們需要努力改善的培訓和認識問題。 上面的健康檢查……也許我們也可以很容易地集成來自 BosunReporter 的指標(可能只有在需要時),從而創(chuàng)建一個功能強大的 API 來檢查服務的健康狀況和狀態(tài)。這將使得我們可以對我們通常推送的指標采用拉式模型。不過,它的代價要盡可能小,配置也要少。 我上面提供了多個我們構(gòu)建和開源的工具。下面是一個供參考的列表。
英文原文:https:///blog/2018/11/29/stack-overflow-how-we-do-monitoring/ 活動推薦 5 月 25-28 日 QCon 全球軟件開發(fā)大會廣州站,大會設(shè)置了「DevOps 最佳實踐」專題以及相關(guān)深度培訓,集結(jié)了當下眾多一線大廠在運維領(lǐng)域的最新探索成果,希望能對各位有所幫助! |
|
來自: 求知_時光 > 《監(jiān)控》