監控即服務:微服務架構的模組化系統

如今,除了整體程式碼之外,我們的專案還包括數十個微服務。 他們每個人都需要被監控。 使用 DevOps 工程師進行如此大規模的工作是有問題的。 我們開發了一個監控系統,為開發人員提供服務。 他們可以獨立地將指標寫入監控系統,使用它們,基於它們建立儀表板,並向它們附加警報,這些警報將在達到閾值時觸發。 對於 DevOps 工程師來說,只有基礎架構和文件。

這篇文章是我與我們的演講的記錄 部分 在 RIT++。 許多人要求我們從那裡製作報告的文本版本。 如果您參加了會議或觀看了視頻,您不會發現任何新內容。 還有其他所有人 - 歡迎來到貓。 我將告訴你我們是如何建立這樣一個系統的,它是如何運作的,以及我們計劃如何更新它。

監控即服務:微服務架構的模組化系統

過去:計劃和計劃

我們是如何得出現在的監控系統的? 要回答這個問題,需要回到2015年。 這是當時的樣子:

監控即服務:微服務架構的模組化系統

我們大約有 24 個節點負責監控。 有一大堆不同的王冠、腳本、守護程序以某種方式監視某些東西、發送訊息和執行功能。 我們認為,我們走得越遠,這樣的系統就越不可行。 開發它是沒有意義的:它太麻煩了。
我們決定選擇保留和開發的監控元素以及放棄的監控元素。 總共有 19 個,只剩下石墨、聚合器和作為儀表板的 Grafana。 但新系統會是什麼樣子呢? 像這樣:

監控即服務:微服務架構的模組化系統

我們有一個指標存儲:這些是石墨,它將基於快速 SSD 驅動器,這些驅動器是某些指標聚合器。 接下來 - Grafana 用於顯示儀表板,Moira 用於警報。 我們還想開發一個用於搜尋異常的系統。

標準:監控2.0

這就是 2015 年的計劃。但是我們不僅要準備基礎設施和服務本身,還要準備其文件。 我們為自己制定了企業標準,我們稱之為監控2.0。 對系統有什麼要求?

  • 持續可用性;
  • 指標儲存間隔 = 10 秒;
  • 指標和儀表板的結構化儲存;
  • SLA > 99,99%
  • 透過 UDP 收集事件指標(!)。

我們需要 UDP,因為我們有大量的流量和產生指標的事件。 如果一次性將它們全部寫入石墨中,儲存就會崩潰。 我們也為所有指標選擇了一級前綴。

監控即服務:微服務架構的模組化系統

每個前綴都有一些屬性。 伺服器、網路、容器、資源、應用程式等都有指標。 清晰、嚴格、類型化的過濾已經實現,我們接受第一級指標並簡單地丟棄其餘的。 這就是我們在 2015 年規劃這個系統的方式。 現在有什麼?

呈現:監控組件互動圖

首先,我們監控應用程式:我們的 PHP 程式碼、應用程式和微服務 - 簡而言之,我們的開發人員編寫的所有內容。 所有應用程式都透過 UDP 將指標傳送到 Brubeck 聚合器(statsd,以 C 重寫)。 事實證明,它是綜合測試中最快的。 它透過 TCP 將已經聚合的指標傳送到 Graphite。

它有一種稱為計時器的指標。 這是一件非常方便的事。 例如,對於連接到服務的每個用戶,您可以向 Brubeck 發送一個包含回應時間的指標。 收到了一百萬個回复,但聚合器只返回了 10 個指標。 你有來訪的人數、最大、最小和平均回應時間、中位數和第四個百分位數。 然後將資料傳輸到 Graphite,我們可以即時看到這一切。

我們也對硬體、軟體、系統指標和我們舊的 Munin 監控系統(它一直為我們工作到 2015 年)進行了匯總。 我們透過 C 守護程式 CollectD 收集所有這些(它內建了一大堆不同的插件,它可以輪詢安裝它的主機系統的所有資源,只需在配置中指定將資料寫入何處)並且透過它將資料寫入Graphite。 它還支援 python 插件和 shell 腳本,因此您可以編寫自己的自訂解決方案:CollectD 將從本機或遠端主機(假設為 Curl)收集此資料並將其發送到 Graphite。

然後我們將收集到的所有指標發送到 Carbon-c-relay。 這是 Graphite 的 Carbon Relay 解決方案,以 C 語言進行了修改。這是一個路由器,用於收集我們從聚合器發送的所有指標並將它們路由到節點。 同樣在路由階段,它會檢查指標的有效性。 首先,它們必須與我之前展示的前綴方案相對應,其次,它們對石墨有效。 否則它們就會掉落。

然後 Carbon-c-relay 將指標傳送到 Graphite 叢集。 我們使用 Go 重寫的 Carbon-cache 作為指標的主要儲存。 由於其多線程,Go-carbon 的性能遠遠優於 Carbon-cache。 它使用 Whisper 套件(標準,用 Python 編寫)接收資料並將其寫入磁碟。 為了從我們的儲存中讀取數據,我們使用 Graphite API。 它比標準 Graphite WEB 快得多。 接下來數據會發生什麼事?

他們去了格拉法納。 我們使用石墨集群作為主要資料來源,此外我們還使用 Grafana 作為顯示指標和建立儀表板的 Web 介面。 對於每項服務,開發人員都會建立自己的儀表板。 然後他們基於它們建立圖表,顯示他們從應用程式編寫的指標。 除了Grafana,我們還有SLAM。 這是一個基於 Graphite 資料計算 SLA 的 Python 惡魔。 正如我已經說過的,我們有幾十個微服務,每個微服務都有自己的要求。 使用 SLAM,我們查看文件並將其與 Graphite 中的內容進行比較,並比較需求與我們服務的可用性的匹配程度。

讓我們更進一步:警報。 它是使用一個強大的系統-莫伊拉(Moira)來組織的。 它是獨立的,因為它有自己的 Graphite。 由 SKB“Kontur”的人員開發,用 python 和 Go 編寫,完全開源。 莫伊拉接收到的流量與進入石墨的流量相同。 如果由於某種原因您的儲存失效了,您的警報仍然有效。

我們在 Kubernetes 中部署了 Moira;它使用 Redis 伺服器叢集作為主資料庫。 結果是一個容錯系統。 它將指標流與觸發器列表進行比較:如果其中沒有提及,則它會刪除該指標。 因此它每分鐘能夠消化千兆位元組的指標。

我們也為其附加了一個企業 LDAP,借助該 LDAP,企業系統的每個使用者都可以根據現有(或新建立的)觸發器為自己建立通知。 由於 Moira 包含 Graphite,因此它支援其所有功能。 因此,您首先將線路複製到 Grafana 中。 查看數據如何在圖表上顯示。 然後你將同一行複製到 Moira 中。 您將其掛起限制並在輸出處收到警報。 要完成這一切,您不需要任何特定知識。 Moira 可以透過簡訊、電子郵件、Jira、Slack 發出警報......它還支援執行自訂腳本。 當觸發器發生在她身上,並且她訂閱了自訂腳本或二進位檔案時,她會運行它並將該二進位檔案的 JSON 發送到 stdin。 因此,您的程式必須解析它。 您將如何處理此 JSON 取決於您。 如果你願意,可以將其發送到 Telegram,如果你願意,可以在 Jira 中開啟任務,執行任何操作。

我們也使用我們自己開發的警報 - Imagotag。 我們對通常用於商店電子價格標籤的面板進行了改造,以滿足我們的需求。 我們從莫伊拉那裡帶來了觸發器。 它表明它們處於什麼狀態以及它們發生的時間。 一些開發人員放棄了 Slack 和電子郵件中的通知,轉而使用此面板。

監控即服務:微服務架構的模組化系統

那麼,由於我們是一家進步的公司,所以我們也在這個系統中監控了 Kubernetes。 我們使用 Heapster 將其包含在系統中,我們將其安裝在叢集中,它收集資料並將其發送到 Graphite。 結果,該圖如下所示:

監控即服務:微服務架構的模組化系統

監控組件

以下是我們用於此任務的元件的連結清單。 它們都是開源的。

石墨:

碳-c-繼電器:

github.com/grobian/carbon-c-relay

布魯貝克:

github.com/github/brubeck

收集到:

收集網站

莫伊拉:

github.com/moira-alert

格拉法納:

grafana.com

堆高機:

github.com/kubernetes/heapster

統計

以下是有關該系統如何為我們運作的一些數據。

聚合器(布魯貝克)

指標數量:~300/秒
向 Graphite 發送指標的時間間隔:30 秒
伺服器資源使用:~ 6% CPU(我們談論的是成熟的伺服器); ~ 1Gb 記憶體; ~3 Mbps 區域網

石墨(碳)

指標數量:~ 1/分鐘
指標更新間隔:30秒
指標儲存方案:30秒35天、5分鐘90天、10分鐘365天(讓您了解服務在很長一段時間內發生了什麼事)
伺服器資源佔用:~10% CPU; ~ 20Gb 內存; ~30 Mbps 區域網

靈活性

我們 Avito 非常重視監控服務的彈性。 他到底為什麼會變成這樣? 首先,它的元件是可以互換的:元件本身及其版本。 其次,支持性。 由於整個專案是開源的,您可以自己編輯程式碼,進行更改,並實現開箱即用的功能。 使用了相當常見的堆棧,主要是 Go 和 Python,因此完成起來非常簡單。

這是一個實際問題的例子。 Graphite 中的測量是一個檔案。 它有一個名字。 檔案名稱 = 指標名稱。 有一種方法可以到達那裡。 Linux 中的檔案名稱限制為 255 個字元。 我們有來自資料庫部門的人員(作為「內部客戶」)。 他們告訴我們:「我們想要監控我們的 SQL 查詢。 它們不是 255 個字符,而是每個 8 MB。 我們希望在 Grafana 中顯示它們,查看此請求的參數,更好的是,我們希望看到此類請求的頂部。 如果能即時顯示那就太好了。 如果能讓他們處於警戒狀態,那真是太酷了。”

監控即服務:微服務架構的模組化系統
範例 SQL 查詢取自 網站 postgrespro.ru

我們設定了一個 Redis 伺服器並使用我們的 Collectd 插件,該插件會轉到 Postgres 並從那裡獲取所有數據,並將指標發送到 Graphite。 但我們用哈希值替換了指標名稱。 我們同時將相同的雜湊值作為鍵傳送到 Redis,並將整個 SQL 查詢作為值傳送到 Redis。 我們所要做的就是確保 Grafana 可以訪問 Redis 並獲取這些資訊。 我們開放 Graphite API 是因為… 這是所有監控元件與 Graphite 互動的主介面,我們在其中輸入一個名為 aliasByHash() 的新函數 - 從 Grafana 中我們取得指標的名稱,並將其在對 Redis 的請求中用作鍵,回應我們得到鍵的值,這是我們的“SQL查詢”” 因此,我們在 Grafana 中顯示了一個 SQL 查詢的顯示,理論上不可能在那裡顯示該查詢,以及它的統計資料(呼叫、行、total_time,...)。

結果

可用性。 我們的監控服務可透過任何應用程式和任何代碼 24/7 提供。 如果您有權存取儲存設施,則可以將資料寫入服務。 語言不重要,決定也不重要。 您只需要知道如何打開套接字、在其中放置度量並關閉套接字。

可靠性。 所有組件都是容錯的並且可以很好地處理我們的負載。

進入門檻低。 為了使用這個系統,您不需要學習 Grafana 中的程式語言和查詢。 只需打開您的應用程序,在其中輸入一個套接字,該套接字將向 Graphite 發送指標,關閉它,打開 Grafana,在其中創建儀表板並查看指標的行為,通過 Moira 接收通知。

獨立。 您可以自己完成這一切,而無需 DevOps 工程師的協助。 這是一個優勢,因為您現在可以監控您的項目,無需詢問任何人 - 無論是開始工作還是進行更改。

我們的目標是什麼?

以下列出的一切不僅僅是抽象的想法,而且至少已經踏出了第一步。

  1. 異常檢測器。 我們想要建立一個服務,該服務將進入我們的 Graphite 儲存並使用各種演算法檢查每個指標。 已經有我們想要查看的演算法,有數據,我們知道如何使用它。
  2. 元數據。 我們有很多服務,它們隨著時間的推移而變化,就像與它們一起工作的人一樣。 持續手動維護文件不是一種選擇。 這就是我們現在將元資料嵌入到微服務中的原因。 它說明了它的開發者、與之互動的語言、SLA 要求、通知應發送到何處以及發送給誰。 部署服務時,所有實體資料都是獨立建立的。 結果,您將獲得兩個連結 - 一個連結到觸發器,另一個連結到 Grafana 中的儀表板。
  3. 每個家庭都有監控。 我們相信所有開發人員都應該使用這樣的系統。 在這種情況下,您始終了解您的流量在哪裡,它發生了什麼,它落在哪裡,它的弱點在哪裡。 例如,如果出現某些情況並使您的服務崩潰,那麼您不會在經理的電話中而是透過警報了解到這一情況,並且您可以立即打開最新日誌並查看那裡發生了什麼。
  4. 高性能。 我們的專案不斷成長,如今每分鐘處理約 2 個指標值。 一年前,這個數字是 000,而且還在繼續增長,這意味著一段時間後 Graphite(whisper)將開始為磁碟子系統帶來沉重的負載。 正如我已經說過的,由於組件的可互換性,該監控系統非常通用。 有人專門為 Graphite 維護並不斷擴展他們的基礎設施,但我們決定走不同的路線:使用 點擊之家 作為我們指標的儲存庫。 這個過渡即將完成,很快我將更詳細地告訴您這是如何完成的:存在哪些困難以及如何克服這些困難,遷移過程如何進行,我將描述選擇作為綁定的組件及其配置。

感謝您的關注! 提出有關該主題的問題,我將嘗試在這裡或在以下帖子中回答。 也許有人有建立類似監控系統或在類似情況下切換到 Clickhouse 的經驗 - 在評論中分享。

來源: www.habr.com

添加評論