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