基於kafka和prometheus的無線APM報警系統設計和實現

基於kafka和prometheus的無線APM報警系統設計和實現

移動APP是當下的主流。公司有很多業務線,有大量的APP。爲了能夠實現對這些APP性能的監控,爲無線開發、測試人員提供性能診斷和分析工具,公司自行開發了無線APM系統。
我們的APM系統設計是這樣的
![avatar][apmbase64]
無線APM系統通過移動端的SDK收集性能數據並上報到無線服務後端。各業務方可以通過無線控制檯,查看經過聚合之後的性能數據。但是,這僅僅只能查看到各種性能數據過去的趨勢。有時候業務方會比較關心實時數據有沒有超過閾值,比如,過去5分鐘之內某個地域的的網絡請求時間均值是否超過了某個值。基於此類需要,需要開發APM的告警功能,當指定的性能指標超過了指定的閾值時,向訂閱告警的業務方以郵件等方式發送通知。在研發告警功能的過程中,前後考慮了多種方案。

通過執行定時任務

我們無線端的APM數據收集之後最終存放在ClickHouse中。最初,
我們設想通過設計一系列定時任務,輪詢ClickHouse中的數據,查詢之後根據設定的條件進行聚合計算,與閾值比較,決定是否進行告警。這種方案如下圖所示
![avatar][pollbase64]
這種方案,對於輕量級,邏輯簡單的指標監控,這個方案是能滿足需求的。但是,如果業務複雜,告警涉及的規則就必須通過程序代碼實現,無法通過標準化的SQL查詢實現。而且,告警監控功能是類似於“滑動窗口”式的,簡單的輪詢並不能完全滿足這種需求。這將造成的後果就是:每添加一個業務數據的監控告警都需要耗費一定的開發資源,而業務使用方也無法進行自定義的告警配置。
鑑於自行開發定時任務的方案有以上缺點,所以我們最終沒有采用這個方案。而是繼續研究以下介紹的方案。

通過Grafana的Alert功能

如前所屬,我們的apm性能數據是保存在ClickHouse中的。而對這些數據的聚合展示,則是通過Grafana。Grafana是一個跨平臺的開源的度量分析和可視化工具,可以通過將採集的數據查詢然後可視化的展示,並及時通知。
Grafana天生具有Alert功能。在grafana的dashboard點擊那個小鈴鐺,就可以創建一個alert。如下圖所示
avatar
這裏可以配置規則的名稱,觸發規則的條件(condition),持續多久之後再出發告警(for)。可以配置告警的接受者,以及告警信息的內容。總體來說,方便好用,而且基本能夠滿足日常的監控告警需求。grafana的告警配置詳細介紹可以參考官方文檔:grafana告警
但是,這對我們來說,有一個問題:雖然我們的各種圖表是用Grafana生成的,但是這些圖表我們是通過鏈接內嵌進我們的控制檯的。告警功能,我們也需要給業務方提供在控制檯的配置入口,可以配置告警條件等參數。Grafana可以提供了HTTP的API,可以對dashboard進行配置,包括Alerting功能。其本質是通過一個大json配置dashboard的各個屬性。具體可以參考Grafana HTTP API一切看着很美好,似乎沿着這條道路我們就可以實現美麗的目標了。但是,Grafana的告警功能,支持以下數據源:Graphite, Prometheus, InfluxDB, Elasticsearch, Stackdriver, Cloudwatch, Azure Monitor, MySQL, PostgreSQL, MSSQL and OpenTSDB。呃,前面說過,我們的數據源是ClickHouse,所以,據說有的版本Grafana已經支持ClickHouse數據源的告警了,但是,我們公司的版本目前還不行。所以,這個方案也只好作罷。這個方案的構想是這樣的
avatar

通過prometheus直接查詢Clickhouse

因爲我們的數據都是存儲到Clickhouse中的,而 Clickhouse 又具備了足夠強大的查詢聚合能力,因此,最初我們設想能夠使用類似存儲過程的方式,通過在 Clickhouse 中添加持續進行的 SQL 運算,並結合某種回調觸發告警。然而,Clickhouse 本身並不支持存儲過程。我們所能做的,是開發一個獨立的服務,持續不斷從 Clickhouse 中查詢業務數據並進行規則匹配。這麼做,似乎又回到了老路上,不可取。
於是,換一種思路,既然一個獨立的監控告警服務不可避免,那麼開源世界中有沒有這麼一種引擎可直接加以應用呢?經過調研,我們發現 Prometheus是一個絕佳的開源解決方案。Prometheus 最初是由 SoundCloud開發,2016年加入雲計算基金會(CNCF),成爲 Kubernetes 之後的第二個託管項目。Prometheus 本身被設計爲一個高性能的時序數據庫,可拉取以標準化形式呈現的數據並進行存儲,同時實現了一種稱爲 PromQL的查詢範式,內置數十種聚合算子。此外,Prometheus 還有一個伴生的告警管理組件 AlertManager,可用於管理 Prometheus 發出的告警,並將告警信息分發至相應的接收通道。
最開始我們的設想,以 Prometheus 標準化導入數據的方式,開發Exporter從 Clickhouse 向 Prometheus 同步數據。由於 Prometheus 本身接收數據採用的是拉取的模式,因此這期間涉及到拉取頻率、拉取時效等問題,並且不同的數據集照樣需要通過在 Exporter 中添加代碼才能進行導出。這種數據同步算不上非常完美。
這種方案的架構如下圖
avatar

通過KSQL+prometheus的方式

如上所屬,prometheus已經爲我們提供了完善的監控告警機制。如果我們能夠解決前一方案的數據實效性的問題,問題的解決將會更趨於完美。而我們的數據,在到達服務端之後,首先是寫入kafka,然後再被Clickhouse消費。如果我們能夠針對Kafka中的流數據進行監控,則能很好的解決監控實時性的問題。而Kafka恰恰提供了相應的功能和工具,就是KSQL。
KSQL是一個用於Apache kafka的流式SQL引擎,KSQL降低了進入流處理的門檻,提供了一個簡單的、完全交互式的SQL接口,用於處理Kafka的數據,可以讓我們在流數據上持續執行 SQL 查詢,KSQL支持廣泛的強大的流處理操作,包括聚合、連接、窗口、會話等等。
這樣,Kafka中原來進入Clickhouse的數據流不變,我們同時增加了KSQL對Kafka中的數據進行一次聚合,然後通過exporter打入prometheus,再通過prometheus的PromQL對這些數據進行二次聚合,並且針對不同的告警規範編寫告警程序,並且根據聚合的結果向AlertManaer發送消息。
以下是這個方案的架構圖
avater

總結

通過以上步驟,我們可以配置絕大多數業務數據的監控規則,利用 Prometheus 的算子,我們甚至可以對某些維度的數據進行預測型監控。但不可否認的是,目前 Prometheus和KSQL 無論是查詢語言或是告警規則的配置,都有一定的學習門檻。我們後續要做的是,開發更細力度的告警規則,滿足業務方多維度的監控告警需求。

通過prometheus直接監控ClickHouse

通過KSQL和promQL

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章