深入淺出Prometheus

1. 簡介

Prometheus 是古希臘神話裡泰坦族的一名神明,名字的意思是“先見之明”,下圖中是 Prometheus 被宙斯懲罰,飽受肝臟日食夜長之苦。

深入淺出Prometheus

下面就是我們 CRUD Boy 所瞭解的 Prometheus,下面是其官網封面圖引導語:From metrics to insight,從指標到洞察力,透過指標去洞察你的系統,為我們的系統提供指標收集和監控的開源解決方案。也就是說,Prometheus 是一個數據監控的解決方案,讓我們能隨時掌握系統執行的狀態,快速定位問題和排除故障。

深入淺出Prometheus

Prometheus 發展速度很快,12 年開發完成,16 年加入 CNCF,成為繼 K8s 之後第二個 CNCF 託管的專案,目前 Github 42k 的 ,而且社群很活躍,維護頻率很高,基本穩定在 1 個月 1 個小版本的迭代速度。

深入淺出Prometheus

2. 整體生態

Prometheus 提供了從指標暴露,到指標抓取、儲存和視覺化,以及最後的監控告警等一系列元件。

深入淺出Prometheus

2.1 指標暴露

每一個被 Prometheus 監控的服務都是一個 Job,Prometheus 為這些 Job 提供了官方的 SDK ,利用這個 SDK 可以自定義並匯出自己的業務指標,也可以使用 Prometheus 官方提供的各種常用元件和中介軟體的 Exporter(比如常用的 MySQL,Consul 等等)。對於短時間執行的指令碼任務或者不好直接 Pull 指標的服務,Prometheus 提供了 PushGateWay 閘道器給這些任務將服務指標主動推 Push 到閘道器,Prometheus 再從這個閘道器裡 Pull 指標。

2.2 指標抓取

上面提到了 Push 和 Pull,其實這是兩種指標抓取模型。

Pull 模型:監控服務主動拉取被監控服務的指標

深入淺出Prometheus

被監控服務一般透過主動暴露 metrics 埠或者透過 Exporter 的方式暴露指標,監控服務依賴服務發現模組發現被監控服務,從而去定期的抓取指標。

Push 模型:被監控服務主動將指標推送到監控服務,可能需要對指標做協議適配,必須得符合監控服務要求的指標格式

深入淺出Prometheus

對於 Prometheus 中的指標抓取,採用的是 Pull 模型,預設是一分鐘去拉取一次指標,透過 Prometheus。yaml 配置檔案中的 scrape_interval 配置項配置,Prometheus 對外都是用的 Pull 模型,一個是 Pull Exporter 的暴露的指標,一個是 Pull PushGateway 暴露的指標。

2.3 指標儲存和查詢

指標抓取後會儲存在內建的時序資料庫中,Prometheus 也提供了 PromQL 查詢語言給我們做指標的查詢,我們可以在 Prometheus 的 WebUI 上透過 PromQL,視覺化查詢我們的指標,也可以很方便的接入第三方的視覺化工具,例如 grafana。

2.4 監控告警

prometheus 提供了 alertmanageer 基於 promql 來做系統的監控告警,當 promql 查詢出來的指標超過我們定義的閾值時,prometheus 會發送一條告警資訊到 alertmanager,manager 會將告警下發到配置好的郵箱或者微信。

3. 工作原理

Prometheus 的從被監控服務的註冊到指標抓取到指標查詢的流程分為五個步驟:

深入淺出Prometheus

3.1 服務註冊

被監控服務在 Prometheus 中是一個 Job 存在,被監控服務的所有例項在 Prometheus 中是一個 target 的存在,所以被監控服務的註冊就是在 Prometheus 中註冊一個 Job 和其所有的 target,這個註冊分為:

靜態註冊

動態註冊

靜態註冊:靜態的將服務的 IP 和抓取指標的埠號配置在 Prometheus yaml 檔案的 scrape_configs 配置下:

scrape_configs: - job_name: “prometheus”   static_configs:   - targets: [“localhost:9090”]

以上就是註冊了一個名為 prometheus 的服務,這個服務下有一個例項,暴露的抓取地址是 localhost:9090。

動態註冊:動態註冊就是在 Prometheus yaml 檔案的 scrape_configs 配置下配置服務發現的地址和服務名,Prometheus 會去該地址,根據你提供的服務名動態發現例項列表,在 Prometheus 中,支援 consul,DNS,檔案,K8s 等多種服務發現機制。

基於 consul 的服務發現:

- job_name: “node_export_consul”  metrics_path: /node_metrics  scheme: http  consul_sd_configs:   - server: localhost:8500     services:     - node_exporter

我們 consul 的地址就是:localhost:8500,服務名是 node_exporter,在這個服務下有一個 exporter 例項:localhost:9600。

深入淺出Prometheus

注意:如果是動態註冊,最好加上這兩配置,靜態註冊指標拉取的路徑會預設的幫我們指定為 metrics_path:/metrics,所以如果暴露的指標抓取路徑不同或者是動態的服務註冊,最好加上這兩個配置。不然會報錯“INVALID“ is not a valid start token,演示下,百度了一下,這裡可能是資料格式不統一導致。

metrics_path: /node_metricsscheme: http

最後可以在 webUI 中檢視發現的例項:

深入淺出Prometheus

目前,Prometheus 支援多達二十多種服務發現協議:

3.2 配置更新

在更新完 Prometheus 的配置檔案後,我們需要更新我們的配置到程式記憶體裡,這裡的更新方式有兩種,第一種簡單粗暴,就是重啟 Prometheus,第二種是動態更新的方式。如何實現動態的更新 Prometheus 配置。

第一步:首先要保證啟動 Prometheus 的時候帶上啟動引數:——web。enable-lifecycle

prometheus ——config。file=/usr/local/etc/prometheus。yml ——web。enable-lifecycle

第二步:去更新我們的 Prometheus 配置:

第三步:更新完配置後,我們可以透過 Post 請求的方式,動態更新配置:

curl -v ——request POST ‘http://localhost:9090/-/reload’

原理:

Prometheus 在 web 模組中,註冊了一個 handler:

if o。EnableLifecycle {  router。Post(“/-/quit”, h。quit)  router。Put(“/-/quit”, h。quit)  router。Post(“/-/reload”, h。reload) // reload配置  router。Put(“/-/reload”, h。reload)}

透過 h。reload 這個 handler 方法實現:這個 handler 就是往一個 channle 中傳送一個訊號:

func (h *Handler) reload(w http。ResponseWriter, r *http。Request) {  rc := make(chan error)  h。reloadCh <- rc  // 傳送一個訊號到channe了中  if err := <-rc; err != nil {   http。Error(w, fmt。Sprintf(“failed to reload config: %s”, err), http。StatusInternalServerError)  }}

在 main 函式中會去監聽這個 channel,只要有監聽到訊號,就會做配置的 reload,重新將新配置載入到記憶體中:

case rc := <-webHandler。Reload():  if err := reloadConfig(cfg。configFile, cfg。enableExpandExternalLabels, cfg。tsdb。EnableExemplarStorage, logger, noStepSubqueryInterval, reloaders。。。); err != nil {   level。Error(logger)。Log(“msg”, “Error reloading config”, “err”, err)   rc <- err  } else {   rc <- nil  }

3.3 指標抓取和儲存

Prometheus 對指標的抓取採取主動 Pull 的方式,即週期性的請求被監控服務暴露的 metrics 介面或者是 PushGateway,從而獲取到 Metrics 指標,預設時間是 15s 抓取一次,配置項如下:

global: scrape_interval: 15s

抓取到的指標會被以時間序列的形式儲存在記憶體中,並且定時刷到磁碟上,預設是兩個小時回刷一次。並且為了防止 Prometheus 發生崩潰或重啟時能夠恢復資料,Prometheus 也提供了類似 MySQL 中 binlog 一樣的預寫日誌,當 Prometheus 崩潰重啟時,會讀這個預寫日誌來恢復資料。

4. Metric 指標

4.1 資料模型

深入淺出Prometheus

Prometheus 採集的所有指標都是以時間序列的形式進行儲存,每一個時間序列有三部分組成:

指標名和指標標籤集合

:metric_name{。。。。},指標名:表示這個指標是監控哪一方面的狀態,比如 http_request_total 表示:請求數量;指標標籤,描述這個指標有哪些維度,比如 http_request_total 這個指標,有請求狀態碼 code = 200/400/500,請求方式:method = get/post 等,實際上指標名稱實際上是以標籤的形式儲存,這個標籤是

name

,即:

name

=。

時間戳

:描述當前時間序列的時間,單位:毫秒。

樣本值

:當前監控指標的具體數值,比如 http_request_total 的值就是請求數是多少。

可以透過檢視 Prometheus 的 metrics 介面檢視所有上報的指標:

深入淺出Prometheus

所有的指標也都是透過如下所示的格式來標識的:

# HELP  // HELP:這裡描述的指標的資訊,表示這個是一個什麼指標,統計什麼的# TYPE  // TYPE:這個指標是什麼型別的{=, 。。。} value  // 指標的具體格式,<指標名>{標籤集合} 指標值

4.2 指標型別

Prometheus 底層儲存上其實並沒有對指標做型別的區分,都是以時間序列的形式儲存,但是為了方便使用者的使用和理解不同監控指標之間的差異,Prometheus 定義了 4 種不同的指標型別:計數器 counter,儀表盤 gauge,直方圖 histogram,摘要 summary。

深入淺出Prometheus

Counter 計數器:

Counter 型別和 redis 的自增命令一樣,只增不減,透過 Counter 指標可以統計 Http 請求數量,請求錯誤數,介面呼叫次數等單調遞增的資料。同時可以結合 increase 和 rate 等函式統計變化速率,後續我們會提到這些內建函式。

深入淺出Prometheus

Gauge 儀表盤:

和 Counter 不同,Gauge 是可增可減的,可以反映一些動態變化的資料,例如當前記憶體佔用,CPU 利用,Gc 次數等動態可上升可下降的資料,在 Prometheus 上透過 Gauge,可以不用經過內建函式直觀的反映資料的變化情況,如下圖表示堆可分配的空間大小:

深入淺出Prometheus

上面兩種是數值指標,代表資料的變化情況,Histogram 和 Summary 是統計型別的指標,表示資料的分佈情況。

Histogram 直方圖:

Histogram 是一種直方圖型別,可以觀察到指標在各個不同的區間範圍的分佈情況,如下圖所示:可以觀察到請求耗時在各個桶的分佈。

深入淺出Prometheus

有一點要注意的是,Histogram 是累計直方圖,即每一個桶的是隻有上區間,例如下圖表示小於 0。1 毫秒(le=“0。1”)的請求數量是 18173 個,小於 0。2 毫秒(le=“0。2”)的請求是 18182 個,在 le=“0。2”這個桶中是包含了 le=“0。1”這個桶的資料,如果我們要拿到 0。1 毫秒到 0。2 毫秒的請求數量,可以透過兩個桶想減得到。

深入淺出Prometheus

在直方圖中,還可以透過 histogram_quantile 函式求出百分位數,比如 P50,P90,P99 等資料

Summary 摘要

Summary 也是用來做統計分析的,和 Histogram 區別在於,Summary 直接儲存的就是百分位數,如下所示:可以直觀的觀察到樣本的中位數,P90 和 P99。

深入淺出Prometheus

Summary 的百分位數是客戶端計算好直接讓 Prometheus 抓取的,不需要 Prometheus 計算,直方圖是透過內建函式 histogram_quantile 在 Prometheus 服務端計算求出。

4.3 指標匯出

指標匯出有兩種方式,一種是使用 Prometheus 社群提供的定製好的 Exporter 對一些元件諸如 MySQL,Kafka 等的指標作匯出,也可以利用社群提供的 Client 來自定義指標匯出。

github。com/prometheus/client_golang/prometheus/promhttp

自定義 Prometheus exporter:

package mainimport (  “net/http”  “github。com/prometheus/client_golang/prometheus/promhttp”)func main() {  http。Handle(“/metrics”, promhttp。Handler())  http。ListenAndServe(“:8080”, nil)}

訪問:http://localhost:8080/metrics,即可看到匯出的指標,這裡我們沒有自定義任何的指標,但是能看到一些內建的Go的執行時指標和promhttp相關的指標,這個Client預設為我們暴露的指標,go_

:以 go

為字首的指標是關於 Go 執行時相關的指標,比如垃圾回收時間、goroutine 數量等,這些都是 Go 客戶端庫特有的,其他語言的客戶端庫可能會暴露各自語言的其他執行時指標。promhttp**:來自 promhttp 工具包的相關指標,用於跟蹤對指標請求的處理。

深入淺出Prometheus

深入淺出Prometheus

新增自定義指標:

package mainimport ( “net/http” “github。com/prometheus/client_golang/prometheus” “github。com/prometheus/client_golang/prometheus/promhttp”)func main() { // 1。定義指標(型別,名字,幫助資訊) myCounter := prometheus。NewCounter(prometheus。CounterOpts{ Name: “my_counter_total”, Help: “自定義counter”, }) // 2。註冊指標 prometheus。MustRegister(myCounter) // 3。設定指標值 myCounter。Add(23) http。Handle(“/metrics”, promhttp。Handler()) http。ListenAndServe(“:8080”, nil)}

執行:

深入淺出Prometheus

模擬下在業務中上報介面請求量:

package mainimport (  “fmt”  “net/http”  “github。com/prometheus/client_golang/prometheus”)var (  MyCounter prometheus。Counter)// init 註冊指標func init() {  // 1。定義指標(型別,名字,幫助資訊)  MyCounter = prometheus。NewCounter(prometheus。CounterOpts{   Name: “my_counter_total”,   Help: “自定義counter”,  })  // 2。註冊指標  prometheus。MustRegister(MyCounter)}// Sayhellofunc Sayhello(w http。ResponseWriter, r *http。Request) {  // 介面請求量遞增  MyCounter。Inc()  fmt。Fprintf(w, “Hello Wrold!”)}

main。go:

package mainimport (  “net/http”  “github。com/prometheus/client_golang/prometheus/promhttp”)func main() {  http。Handle(“/metrics”, promhttp。Handler())  http。HandleFunc(“/counter”,Sayhello)  http。ListenAndServe(“:8080”, nil)}

一開始啟動時,指標 counter 是 0:

深入淺出Prometheus

呼叫:/counter 介面後,指標資料發生了變化,這樣就可以簡單實現了介面請求數的統計:

深入淺出Prometheus

對於其他指標定義方式是一樣的:

var (  MyCounter prometheus。Counter  MyGauge prometheus。Gauge  MyHistogram prometheus。Histogram  MySummary prometheus。Summary)// init 註冊指標func init() {  // 1。定義指標(型別,名字,幫助資訊)  MyCounter = prometheus。NewCounter(prometheus。CounterOpts{   Name: “my_counter_total”,   Help: “自定義counter”,  })  // 定義gauge型別指標  MyGauge = prometheus。NewGauge(prometheus。GaugeOpts{   Name: “my_gauge_num”,   Help: “自定義gauge”,  })  // 定義histogram  MyHistogram = prometheus。NewHistogram(prometheus。HistogramOpts{   Name: “my_histogram_bucket”,   Help: “自定義histogram”,   Buckets: []float64{0。1,0。2,0。3,0。4,0。5},  // 需要指定桶  })  // 定義Summary  MySummary = prometheus。NewSummary(prometheus。SummaryOpts{   Name: “my_summary_bucket”,   Help: “自定義summary”,   // 這部分可以算好後在set   Objectives: map[float64]float64{     0。5: 0。05,     0。9: 0。01,     0。99: 0。001,   },  })  // 2。註冊指標  prometheus。MustRegister(MyCounter)  prometheus。MustRegister(MyGauge)  prometheus。MustRegister(MyHistogram)  prometheus。MustRegister(MySummary)}

深入淺出Prometheus

上面的指標都是沒有設定標籤的,我們一般的指標都是帶有標籤的,如何設定指標的標籤呢?

如果我要設定帶標籤的 counter 型別指標,只需要將原來的 NewCounter 方法替換為 NewCounterVec 方法即可,並且傳入標籤集合。

MyCounter *prometheus。CounterVec// 1。定義指標(型別,名字,幫助資訊)MyCounter = prometheus。NewCounterVec(  prometheus。CounterOpts{  Name: “my_counter_total”,  Help: “自定義counter”,  },  // 標籤集合  []string{“label1”,“label2”},)// 帶標籤的set指標值MyCounter。With(prometheus。Labels{“label1”:“1”,“label2”:“2”})。Inc()

深入淺出Prometheus

其他同理。

5. PromQL

剛剛提到了 Prometheus 中指標有哪些型別以及如何匯出我們的指標,現在指標匯出到 Prometheus 了,利用其提供的 PromQL 可以查詢我們匯出的指標。

PromQL 是 Prometheus 為我們提供的函式式的查詢語言,查詢表示式有四種類型:

字串:只作為某些內建函式的引數出現

標量:單一的數字值,可以是函式引數,也可以是函式的返回結果

瞬時向量:某一時刻的時序資料

區間向量:某一時間區間內的時序資料集合

5.1 瞬時查詢

直接透過指標名即可進行查詢,查詢結果是當前指標最新的時間序列,比如查詢 Gc 累積消耗的時間:

go_gc_duration_seconds_count

深入淺出Prometheus

img

我們可以看到查詢出來有多個同名指標結果,可以用{}做標籤過濾查詢:比如我們想查指定例項的指標。

go_gc_duration_seconds_count{instance=“127。0。0。1:9600”}

深入淺出Prometheus

而且也支援則表示式,透過=~指定正則表示式,如下所示:查詢所有 instance 是 localhost 開頭的指標。

go_gc_duration_seconds_count{instance=~“localhost。*”}

深入淺出Prometheus

5.2 範圍查詢

範圍查詢的結果集就是區間向量,可以透過[]指定時間來做範圍查詢,查詢 5 分鐘內的 Gc 累積消耗時間:

go_gc_duration_seconds_count{}[5m]

注意:這裡範圍查詢第一個點並不一定精確到剛剛好 5 分鐘前的那個時序樣本點,他是以 5 分鐘作為一個區間,尋找這個區間的第一個點到最後一個樣本點。

深入淺出Prometheus

時間單位:

深入淺出Prometheus

d:天,h:小時,m:分鐘,ms:毫秒,s:秒,w:周,y:年

同樣支援類似 SQL 中的 offset 查詢,如下:查詢一天前當前 5 分鐘前的時序資料集:

go_gc_duration_seconds_count{}[5m] offset 1d

5.3 內建函式

Prometheus 內建了很多函式,這裡主要記錄下常用的幾個函式的使用:

rate 和 irate 函式:

rate 函式可以用來求指標的平均變化速率

rate函式=時間區間前後兩個點的差 / 時間範圍

一般 rate 函式可以用來求某個時間區間內的請求速率,也就是我們常說的 QPS:

深入淺出Prometheus

但是 rate 函式只是算出來了某個時間區間內的平均速率,沒辦法反映突發變化,假設在一分鐘的時間區間裡,前 50 秒的請求量都是 0 到 10 左右,但是最後 10 秒的請求量暴增到 100 以上,這時候算出來的值可能無法很好的反映這個峰值變化。這個問題可以透過 irate 函式解決,irate 函式求出來的就是瞬時變化率。

時間區間內最後兩個樣本點的差 / 最後兩個樣本點的時間差

深入淺出Prometheus

可以透過影象看下兩者的區別:irate 函式的影象峰值變化大,rate 函式變化較為平緩。

rate 函式:

深入淺出Prometheus

irate 函式:

深入淺出Prometheus

聚合函式:Sum() by() without()

也是上邊的例子,我們在求指定介面的 QPS 的時候,可能會出現多個例項的 QPS 的計算結果,如下是存在多個介面,三個服務的 QPS。

rate(demo_api_request_duration_seconds_count{job=“demo”, method=“GET”, status=“200”}[5m])

深入淺出Prometheus

利用 sum 函式可以將三個 QPS 聚合,即可得到整個服務該介面的 QPS:其實 Sum 就是將指標值做相加。

深入淺出Prometheus

但是這樣直接的相加太籠統抽象了,可以配合 by 和 without 函式在 sum 的時候,基於某些標籤分組,類似 SQL 中的 group by

例如,我可以根據請求介面標籤分組:這樣拿到的就是具體介面的 QPS:

sum(rate(demo_api_request_duration_seconds_count{job=“demo”, method=“GET”, status=“200”}[5m])) by(path)

深入淺出Prometheus

也可以不根據介面路徑分組:透過 without 指定:

sum(rate(demo_api_request_duration_seconds_count{job=“demo”, method=“GET”, status=“200”}[5m])) without(path)

深入淺出Prometheus

可以透過 histogram_quantile 函式做資料統計:可以用來統計百分位數:第一個引數是百分位,第二個 histogram 指標,這樣計算出來的就是中位數,即 P50

histogram_quantile(0。5,go_gc_pauses_seconds_total_bucket)

深入淺出Prometheus

分享之前和同事一起發現的坑:

在剛剛寫的自定義 exporter 上新增幾個 histogram 的樣本點:

MyHistogram。Observe(0。3)MyHistogram。Observe(0。4)MyHistogram。Observe(0。5)

histogram 的桶設定:

MyHistogram = prometheus。NewHistogram(prometheus。HistogramOpts{  Name: “my_histogram_bucket”,  Help: “自定義histogram”,  Buckets: []float64{0,2。5,5,7。5,10},  // 需要指定桶})

如果這樣的話,所有指標都會直接進入到第一個桶,即 0 到 2。5 這個桶,如果我要計算中位數,那麼這個中位數按照數學公式來算的話,肯定是在 0 到 2。5 之間的,而且肯定是 0。3 到 0。5 之間。

我用

histogram_quantile 函式

計算下:計算結果是 1。25,其實已經不對了。

histogram_quantile(0。5,my_histogram_bucket_bucket)

深入淺出Prometheus

我在計算下 P99,等於 2。475:

histogram_quantile(0。99,my_histogram_bucket_bucket)

深入淺出Prometheus

我的指標都是不大於 1 的,為啥算出來的 P50 和 P99 都這麼離譜呢?

這是因為 Prometheus 他是不儲存你具體的指標數值的,他會幫你把指標放到具體的桶,但是他不會儲存你指標的值,計算的分位數是一個預估的值,怎麼預估呢?就是假設每個桶內的樣本分佈是均勻的,線性分佈來計算的,比如剛剛的 P50,其實就是算排在第 50%位置的樣本值,因為剛剛所有的資料都落在了第一個桶,那麼他在計算的時候就會假定這個 50%值在第一個桶的中點,他就會假定這個數就是 0。5 _ 2。5,P99 就是第一個桶的 99%的位置,他就會假定這個數就是 0。99 _ 2。5。

導致這個誤差較大的原因就是我們的 bucket 設定的不合理。

重新定義桶:

// 定義histogramMyHistogram = prometheus。NewHistogram(prometheus。HistogramOpts{  Name: “my_histogram_bucket”,  Help: “自定義histogram”,  Buckets: []float64{0。1,0。2,0。3,0。4,0。5},  // 需要指定桶})

上報資料:

MyHistogram。Observe(0。1)MyHistogram。Observe(0。3)MyHistogram。Observe(0。4)

深入淺出Prometheus

重新計算 P50,P99:

深入淺出Prometheus

深入淺出Prometheus

桶設定的越合理,計算的誤差越小

6. Grafana 視覺化

除了可以利用 Prometheus 提供的 webUI 視覺化我們的指標外,還可以接入 Grafana 來做指標的視覺化。

第一步,對接資料來源:

深入淺出Prometheus

配置好 prometheus 的地址:

深入淺出Prometheus

第二步:建立儀表盤

深入淺出Prometheus

編輯儀表盤:

深入淺出Prometheus

在 metrics 處編寫 PromQL 即可完成查詢和視覺化:

深入淺出Prometheus

儀表盤編輯完後,可以匯出對應的 json 檔案,方便下次匯入同樣的儀表盤:

深入淺出Prometheus

以上是我之前搭建的儀表盤:

深入淺出Prometheus

7. 監控告警

AlertManager 是 prometheus 提供的告警資訊下發元件,包含了對告警資訊的分組,下發,靜默等策略。配置完成後可以在 webui 上看到對應的告警策略資訊。告警規則也是基於 PromQL 進行定製的。

編寫告警配置:當 Http_srv 這個服務掛了,Prometheus 採集不到指標,並且持續時間 1 分鐘,就會觸發告警

groups:\- name: simulator-alert-rule rules: \- alert: HttpSimulatorDown  expr: sum(up{job=“http_srv”}) == 0  for: 1m  labels:   severity: critical

在 prometheus。yml 中配置告警配置檔案,需要配置上 alertmanager 的地址和告警檔案的地址

\# Alertmanager configurationalerting: alertmanagers: \- static_configs:  \- targets: [‘localhost:9093’]\# Load rules once and periodically evaluate them according to the global ‘evaluation_interval’。rule_files:  \- “alert_rules。yml”  \#- “first_rules。yml”

配置告警資訊,例如告警傳送地址,告警內容模版,分組策略等都在 alertmanager 的配置檔案中配置:

global: smtp_smarthost: ‘smtp。qq。com:465’ smtp_from: ‘xxxx@qq。com’ smtp_auth_username: ‘xxxx@qq。com’ smtp_auth_password: ‘xxxx’ smtp_require_tls: falseroute: group_interval: 1m repeat_interval: 1m receiver: ‘mail-receiver’# group_by       //採用哪個標籤作為分組# group_wait      //分組等待的時間,收到報警不是立馬傳送出去,而是等待一段時間,看看同一組中是否有其他報警,如果有一併傳送# group_interval    //告警時間間隔# repeat_interval   //重複告警時間間隔,可以減少傳送告警的頻率# receiver       //接收者是誰# routes        //子路由配置receivers:\- name: ‘mail-receiver’ email_configs:  \- to: ‘xxxx@qq。com’

當我 kill 程序:

深入淺出Prometheus

prometheus 已經觸發告警:

深入淺出Prometheus

在等待 1 分鐘,如果持續還是符合告警策略,則狀態為從 pending 變為 FIRING 會發送郵件到我的郵箱

深入淺出Prometheus

此時我的郵箱收到了一條告警訊息:

深入淺出Prometheus

alertmanager 也支援對告警進行靜默,在 alertmanager 的 WEBUI 中配置即可:

深入淺出Prometheus

間隔了 4 分鐘,沒有收到告警,靜默生效:

深入淺出Prometheus

一個小時沒有收到告警資訊:

深入淺出Prometheus

8. 參考文獻

Pull or Push?監控系統如何選型-阿里雲開發者社群

為 go 應用新增 prometheus 監控指標 - SegmentFault 思否

GitHub - prometheus/client_golang: Prometheus instrumentation library for Go applications

Material for MkDocs - Prometheus 入門到實戰

終於有人把 Prometheus 入門講明白了 - DockOne.io

Prometheus 報警 AlertManager 實戰-陽明的部落格|Kubernetes|Istio|Prometheus|Python|Golang|雲原生

如何熱載入新配置 · Prometheus 實戰

https://www。youtube。com/watch?v=qB40kqhTyYM&t=2261s

https://www。youtube。com/watch?v=SOTxSSiLtuA&t=141s