史上最全:prometheus+alertmanager 實現監控預警

文章很長,且持續更新,建議收藏起來,慢慢讀!瘋狂創客圈總目錄 博客園版 爲您奉上珍貴的學習資源 :

免費贈送 :《尼恩Java面試寶典》 持續更新+ 史上最全 + 面試必備 2000頁+ 面試必備 + 大廠必備 +漲薪必備
免費贈送 :《尼恩技術聖經+高併發系列PDF》 ,幫你 實現技術自由,完成職業升級, 薪酬猛漲!加尼恩免費領
免費贈送 經典圖書:《Java高併發核心編程(卷1)加強版》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領
免費贈送 經典圖書:《Java高併發核心編程(卷2)加強版》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領
免費贈送 經典圖書:《Java高併發核心編程(卷3)加強版》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領

免費贈送 資源寶庫: Java 必備 百度網盤資源大合集 價值>10000元 加尼恩領取


史上最全:prometheus+alertmanager 實現監控預警

尼恩說在前面

在40歲老架構師 尼恩的讀者交流羣(50+)中,最近有小夥伴拿到了一線互聯網企業如得物、阿里、滴滴、極兔、有贊、希音、百度、網易、美團的面試資格,遇到很多很重要監控預警類的面試題:

怎麼做 指標的治理?

怎麼做監控預警?

很多很多小夥伴遇到這樣的難題,但是沒有實操過,也瞭解不全面,導致丟了一些很好的機會。

尼恩結合自己的《10WqpsNetty網關實操操作》,給大家梳理 一本配套的《Prometheus聖經》,幫助大家一招制敵。

同時,把這個指標監控預警相關面試題, 也收入咱們的 《尼恩Java面試寶典PDF》V175版本《架構專題》,供後面的小夥伴參考,提升大家的 3高 架構、設計、開發水平。

《尼恩 架構筆記》《尼恩高併發三部曲》《尼恩Java面試寶典》《Prometheus聖經》的PDF,請到文末公號【技術自由圈】獲取

Prometheus聖經的上下兩部分

  • prometheus學習聖經Part1:使用prometheus+Grafana實現指標監控

  • prometheus學習聖經Part2:使用prometheus+Alertmanager實現指標預警

在這裏插入圖片描述

完整的PDF,請在 技術自由圈 公衆號獲取。

在這裏插入圖片描述

1. prometheus學習聖經(下):使用prometheus+alertmanager 實現指標預警

監控和告警,是孿生兄弟,監控就需要報警,沒有報警的監控是不完善的。

那麼prometheus生態,報警究竟是怎麼實現呢,告警組件它又是怎麼和prometheus一起協調,並且完成報警的發送呢?

先來看一下, prometheus的官方生態架構圖

在這裏插入圖片描述

prometheus可以抓取exporter中暴露出來的指標數據並且存儲,prometheus有自己的查詢語句PromQL,

grafana面板中的顯示的都是PromQL查詢prometheus時序數據庫出來的數據。

和grafana一樣,告警組件alertmanager也是依靠prometheus的PromQL,具體的流程大致是:在prometheus中可以定義一些PromQL語句,當語句查詢出來的值超過預定的閾值,prometheus發送報警給alertmanager了,

alertmanager負責把prometheus發送過去的相關的報警指標分類,並且執行報警(微信,郵件,企微)

Prometheus的架構中被劃分爲兩個部分,

  1. 在Prometheus Server中定義告警規則,以及產生告警,

  2. Alertmanager組件則用於處理這些由Prometheus產生的告警。

    Alertmanager即Prometheus體系中告警的統一處理中心。Alertmanager提供了多種內置第三方告警通知方式,同時還提供了對Webhook通知的支持,通過Webhook用戶可以完成對告警更多個性化的擴展。

prometheus觸發一條告警的過程:
prometheus—>觸發閾值—>超出持續時間—>alertmanager—>分組|抑制|靜默—>媒體類型—>郵件|釘釘|微信等。

在這裏插入圖片描述

在這裏插入圖片描述

Alertmanager: 從 Prometheus server 端接收到 alerts 後,會進行去重,分組,並路由到相應的接收方,發出報警,常見的接收方式有:電子郵件,微信,釘釘, slack等。

在Prometheus中一條告警規則主要由以下幾部分組成

  1. 告警名稱:用戶需要爲告警規則命名,當然對於命名而言,需要能夠直接表達出該告警的主要內容
  2. 告警規則:告警規則實際上主要由PromQL進行定義,其實際意義是當表達式(PromQL)查詢結果持續多長時間(During)後出發告警

2.自定義告警規則

Prometheus中的告警規則允許你基於PromQL表達式定義告警觸發條件,Prometheus後端對這些觸發規則進行週期性計算,當滿足觸發條件後則會觸發告警通知。

默認情況下,用戶可以通過Prometheus的Web界面查看這些告警規則以及告警的觸發狀態。

當Promthues與Alertmanager關聯之後,可以將告警發送到外部服務如Alertmanager中並通過Alertmanager可以對這些告警進行進一步的處理。

prometheus 告警規則的案例

先來一個簡單點的案例

groups:
- name: example
  rules:
  - alert: HighErrorRate
    expr: job:request_latency_seconds:mean5m{job="myjob"} > 0.5
    for: 10m
    labels:
      severity: page
    annotations:
      summary: High request latency
      description: description info


下面是尼恩用來做直接內存閾告警的例子:

groups:
# 報警組組名稱
- name: DirectMemoryAlert
  #報警組規則
  rules:
   #告警名稱,需唯一
  - alert: DirectMemoryAlert
    #promQL表達式
    expr:  gateway_direct_memory  > 5
    #滿足此表達式持續時間超過for規定的時間纔會觸發此報警
    for: 1m
    labels:
      #嚴重級別
      severity: page
    annotations:
     #發出的告警標題
      summary: "實例 {{ $labels.instance }} 直接內存使用超過 5M"
      #發出的告警內容
      description: "實例{{ $labels.instance }} 直接內存使用超過 5M, (當前值爲: {{ $value }})M"

可以將一組相關的規則設置定義在一個group下。 在每一個group中定義多個告警規則(rule)。

告警規則主要由以下幾部分組成

  • alert:告警規則的名稱。
  • expr:基於PromQL表達式告警觸發條件,用於計算是否有時間序列滿足該條件。
  • for:評估等待時間,可選參數。用於表示只有當觸發條件持續一段時間後才發送告警。在等待期間新產生告警的狀態爲pending。
  • labels:自定義標籤,允許用戶指定要附加到告警上的一組附加標籤。
  • annotations:用於指定一組附加信息,比如用於描述告警詳細信息的文字等,annotations的內容在告警產生時會一同作爲參數發送到Alertmanager。

讓Prometheus啓用定義的告警規則

在Prometheus全局配置文件中,通過 rule_files 指定一組告警規則文件的訪問路徑,路徑下存放告警規則文件

Prometheus啓動後會自動掃描這些路徑下告警規則文件中定義的內容,並且根據這些規則計算是否向外部發送通知:

rule_files:
  [ - <filepath_glob> ... ]

默認情況下, Prometheus會每分鐘對這些告警規則進行計算,注意週期是 每分鐘。

如果用戶想 自定義的告警計算週期 ,則可以通過evaluation_interval來覆蓋默認的計算週期:

global:
  [ evaluation_interval: <duration> | default = 1m ]

prometheus告警規則文件的模板化

在告警規則文件的annotations中,有兩個重要的、關於規則的描述信息項目:

  • summary:描述告警的概要信息,
  • description: 描述告警的詳細信息。

除了Prometheus之外,同時Alertmanager的UI也會根據這兩個標籤值,顯示告警信息。

爲了提升可讀性,Prometheus支持模板化label和annotations的中標籤的值,通過表達式去訪問。

比如,通過下面兩個表達式,可以訪問數據序列中的 標籤和樣本值:

  • $labels.變量 ,這個表達式可以訪問當前告警實例中指定標籤的值。

  • $value ,這個表達式則可以獲取當前PromQL表達式計算的樣本值。

# To insert a firing element's label values:
{{ $labels.<labelname> }}
# To insert the numeric expression value of the firing element:
{{ $value }}


舉個例子,以通過模板化優化summary以及description的內容的可讀性

- alert: KubeAPILatencyHigh
  annotations:
    message: The API server has a 99th percentile latency of {{ $value }} seconds
      for {{ $labels.verb }} {{ $labels.resource }}.
  expr: |
    cluster_quantile:apiserver_request_latencies:histogram_quantile{job="apiserver",quantile="0.99",subresource!="log"} > 4
  for: 10m
  labels:
    severity: critical

這條警報的大致含義是,假如 kube-apiserver 的 P99 響應時間大於 4 秒,並持續 10 分鐘以上,就產生報警。

首先要注意的是由 for 指定的 Pending Duration (持續時間)。

這個 for 參數主要用於降噪,很多類似響應時間這樣的指標都是有抖動的,通過指定 Pending Duration,我們可以 過濾掉這些瞬時抖動,讓 on-call 人員能夠把注意力放在真正有持續影響的問題上。

那麼顯然,下面這樣的狀況是不會觸發這條警報規則的,因爲雖然指標已經達到了警報閾值,但持續時間並不夠長:

查看告警規則和狀態

可以通過Prometheus WEB界面中的Alerts菜單查,看當前Prometheus下的所有告警規則,以及其當前所處的活動狀態。

在這裏插入圖片描述狀態說明Prometheus Alert 告警狀態有三種狀態:Inactive、Pending、Firing。

  • 1、Inactive:非活動狀態,表示正在監控,但是還未有任何警報觸發。
  • 2、Pending:表示這個警報必須被觸發。由於警報可以被分組、壓抑/抑制或靜默/靜音,所
    以警報等待驗證,一旦所有的驗證都通過,則將轉到Firing 狀態。
  • 3、Firing:將警報發送到AlertManager,它將按照配置將警報的發送給所有接收者。一旦警
    報解除,則將狀態轉到Inactive,如此循環。

表示這個警報必須被觸發。 警報等待驗證,告警觸發條件滿足,但 for 定義的持續時間不滿足。

在這裏插入圖片描述

Firing:將警報發送到AlertManager,它將按照配置將警報的發送給所有接收者。

在這裏插入圖片描述

對於已經pending或者firing的告警,Prometheus也會將它們存儲到時間序列ALERTS{}中。 可以通過表達式,查詢告警實例:

ALERTS{alertname="<alert name>", alertstate="pending|firing", <additional alert labels>}

樣本值爲1表示當前告警處於活動狀態(pending或者firing),當告警從活動狀態轉換爲非活動狀態時,樣本值則爲0。

Prometheus fire 之後

Prometheus fire 之後 將警報發送到AlertManager,

在這裏插入圖片描述

AlertManager 將按照配置將警報的發送給所有接收者。

尼恩的直接內存告警案例中, 接受者是一個 webhook,收到告警的時候,斷點被命中。

在這裏插入圖片描述

回顧一下:prometheus配置基礎規則

prometheus.yml 屬性配置

屬性 描述
scrape_interval 樣本採集週期,默認爲1分鐘採集一次
evaluation_interval 告警規則計算週期,默認爲1分鐘計算一次
rule_files 指定告警規則的文件
scrape_configs job的配置項,裏面可配多組job任務
job_name 任務名稱,需要唯一性
static_configs job_name的配置選項,一般使用file_sd_configs 熱加載配置
file_sd_configs job_name的動態配置選項,使用此配置可以實現配置文件的熱加載
files: file_sd_configs配置的服務發現的文件路徑列表,支持.json,.yml或.yaml,路徑最後一層支持通配符*
refresh_interval file_sd_configs中的files重新加載的週期,默認5分鐘

下面是一個完整的參考案例:

# my global config
global:
  scrape_interval:     15s # 採樣週期
  evaluation_interval: 15s # 告警規則計算週期

# Alertmanager configuration
alerting:
  alertmanagers:
  - static_configs:
    - targets:
      - alertmanager:9093

# 報警規則文件可以指定多個,並且可以使用通配符*
rule_files:
  - "rules/*_rules.yml"
  # - "second_rules.yml"

# 採集job配置
scrape_configs:
  - job_name: 'prometheus'
    #使用file_sd_configs熱加載配置文件
    file_sd_configs:
      #指定1分鐘加載一次配置
    - refresh_interval: 1m
      files:
      - config_prometheus.json
  
  - job_name: 'linux_base'
    file_sd_configs:
    - refresh_interval: 1m
      files:
      - config_exporter.json
      
  - job_name: 'service_base'
    file_sd_configs:
    - refresh_interval: 1m
      files:
      - config_mtail.json
      
  - job_name: 'grafana'
    file_sd_configs:
    - refresh_interval: 1m
      files:
      - config_grafana.json



此處我們使用rule_files屬性來設置告警文件,這裏設置報警規則,rules/host_rules.yml

groups:
# 報警組組名稱
- name: hostStatsAlert
  #報警組規則
  rules:
   #告警名稱,需唯一
  - alert: hostCpuUsageAlert
    #promQL表達式
    expr: sum(avg without (cpu)(irate(node_cpu_seconds_total{mode!='idle'}[5m]))) by (instance) > 0.85
    #滿足此表達式持續時間超過for規定的時間纔會觸發此報警
    for: 1m
    labels:
      #嚴重級別
      severity: page
    annotations:
     #發出的告警標題
      summary: "實例 {{ $labels.instance }} CPU 使用率過高"
      #發出的告警內容
      description: "實例{{ $labels.instance }} CPU 使用率超過 85% (當前值爲: {{ $value }})"
  - alert: hostMemUsageAlert
    expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes)/node_memory_MemTotal_bytes > 0.85
    for: 1m
    labels:
      severity: page
    annotations:
      summary: "實例 {{ $labels.instance }} 內存使用率過高"
      description: "實例 {{ $labels.instance }} 內存使用率 85% (當前值爲: {{ $value }})"

下面是尼恩用來做直接內存閾值監控的例子 directmemory_rules.yml

groups:
# 報警組組名稱
- name: DirectMemoryAlert
  #報警組規則
  rules:
   #告警名稱,需唯一
  - alert: DirectMemoryAlert
    #promQL表達式
    expr:  gateway_direct_memory  > 5
    #滿足此表達式持續時間超過for規定的時間纔會觸發此報警
    for: 1m
    labels:
      #嚴重級別
      severity: page
    annotations:
     #發出的告警標題
      summary: "實例 {{ $labels.instance }} 直接內存使用超過 5M"
      #發出的告警內容
      description: "實例{{ $labels.instance }} 直接內存使用超過 5M, (當前值爲: {{ $value }})M"

3. Alertmanager 的警報管理能力:

  • Prometheus負責中配置警報規則,將警報發送到Alertmanager 。
  • Alertmanager 負責管理這些警報,包括沉默,抑制,合併和發送通知 。

Alertmanager 發送通知有多種方式,其內部集成了郵箱、Slack、企業微信、webhook等方式,

網上也有大量例子實現對第三方軟件的集成,如釘釘等。

本文介紹郵件報警方式和通過使用java來搭建webhook自定義通知報警的方式。

3.1 Alertmanager的特性

Alertmanager除了提供基本的告警通知能力以外,還主要提供瞭如:分組、抑制以及靜默等告警特性
在這裏插入圖片描述

3.2告警的分組

分組(group): 將類似性質的警報合併爲單個通知。

在某些情況下,比如由於系統宕機導致大量的告警被同時觸發,在這種情況下分組機制可以將這些被觸發的告警合併爲一個告警通知.

告警的分組 避免一次性接受大量的告警通知,而無法對問題進行快速定位。

例如,當集羣中有數百個正在運行的服務實例,並且爲每一個實例設置了告警規則。

假如此時發生了網絡故障,可能導致大量的服務實例無法連接到數據庫,結果就會有數百個告警被髮送到Alertmanager。

而作爲用戶,可能只希望能夠在一個通知中就能查看哪些服務實例收到影響。

這時可以按照服務所在集羣或者告警名稱對告警進行分組,而將這些告警內聚在一起成爲一個通知。

告警分組,告警時間,以及告警的接受方式可以通過Alertmanager的配置文件進行配置。

3.3告警的抑制

抑制(inhibition): 當警報發出後,停止重複發送由此警報引發的其他警報,即合併一個故障引起的多個報警事件,可以 消除冗餘告警

例如,當集羣不可訪問時觸發了一次告警,通過配置Alertmanager可以忽略與該集羣有關的其它所有告警。這樣可以避免接收到大量與實際問題無關的告警通知。

抑制機制同樣通過Alertmanager的配置文件進行設置。

3.3告警的靜默

靜默(silences): 是一種簡單的特定時間靜音的機制,

例如:服務器要升級維護可以先設置這個時間段告警靜默。

靜默提供了一個簡單的機制, 可以快速根據標籤對告警進行靜默處理。

如果接收到的告警符合靜默的配置,Alertmanager則不會發送告警通知。

靜默設置需要在Alertmanager的Werb頁面上進行設置。

4.alertmanager配置及部署

4.1.alertmanager配置

alertmanager會定義一個基於標籤匹配規則的路由樹,用以接收到報警後根據不同的標籤匹配不同的路由,來將報警發送給不同的receiver。

global:
  resolve_timeout: 5m

route:
  group_by: ['alertname']
  group_wait: 10s
  group_interval: 1m
  repeat_interval: 4h
  receiver: 'webhook'
receivers:
- name: 'webhook'
  webhook_configs:
    - url: 'http://192.168.56.1:28088/alert-demo/hook/demo'	

如果只是定義一個路由route,則這個路由需要接收並處理所有的報警,

如果需要區分不同的報警發送給不同的receiver,則需要配置多個子級route來處理不同的報警,而根route此時必須能夠接收處理所有的報警。

下面是來自於互聯網的其他小夥伴的,一個多個子級route來處理不同的報警的例子

#根路由
route:
  #頂級路由配置的接收者(匹配不到子級路由,會使用根路由發送報警)
  receiver: 'default-receiver'
  #設置等待時間,在此等待時間內如果接收到多個報警,則會合併成一個通知發送給receiver
  group_wait: 30s
  #兩次報警通知的時間間隔,如:5m,表示發送報警通知後,如果5分鐘內再次接收到報警則不會發送通知
  group_interval: 5m
  #發送相同告警的時間間隔,如:4h,表示4小時內不會發送相同的報警
  repeat_interval: 4h
  #分組規則,如果滿足group_by中包含的標籤,則這些報警會合併爲一個通知發給receiver
  group_by: [cluster, alertname]
  routes:
  #子路由的接收者
  - receiver: 'database-pager'
    group_wait: 10s
    #默認爲false。false:配置到滿足條件的子節點點後直接返回,true:匹配到子節點後還會繼續遍歷後續子節點
    continue:false
    #正則匹配,驗證當前標籤service的值是否滿足當前正則的條件
    match_re:
      service: mysql|cassandra
  #子路由的接收者
  - receiver: 'frontend-pager'
    group_by: [product, environment]
    #字符串匹配,匹配當前標籤team的值爲frontend的報警
    match:
      team: frontend

#定義所有接收者
receivers:
#接收者名稱
- name: 'default-receiver'
  #接收者爲webhook類型
  webhook_configs:
  #webhook的接收地址
  - url: 'http://127.0.0.1:5001/'
- name: 'database-pager'
  webhook_configs:
  - url: 'http://127.0.0.1:5002/'
- name: 'frontend-pager'
  webhook_configs:
  - url: 'http://127.0.0.1:5003/'

4.2.alertmanager部署

使用尼恩的一鍵部署腳本,就可以了

version: "3.5"
services:
  prometheus:
    image: prom/prometheus:v2.30.0
    container_name: prometheus
    volumes:
     - /tmp:/tmp
     - ./prometheus.yml:/etc/prometheus/prometheus.yml
     - ./rules:/rules
    command: "--config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/prometheus --storage.tsdb.wal-compression --storage.tsdb.retention.time=7d"
    hostname: prometheus
    environment:
      TZ: "Asia/Shanghai"
    ports:
      - "9090:9090"
    networks:
       base-env-network:
         aliases:
          - prometheus

  alertmanager:
    image: prom/alertmanager:v0.23.0
  #		restart: always
    container_name: alertmanager
    hostname: alertmanager
    environment:
      TZ: "Asia/Shanghai"
    ports:
    - 9093:9093
    command:
      - "--config.file=/etc/alertmanager/alertmanager.yml"
      - "--log.level=debug"
    volumes:
    - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
    - ./alertmanager:/alertmanager


其中涉及到直接內存的告警配置, 修改alertmanager.yml,內容如下:

global:
  resolve_timeout: 5m

route:
  group_by: ['alertname']
  group_wait: 10s
  group_interval: 1m
  repeat_interval: 4h
  receiver: 'webhook'
receivers:
- name: 'webhook'
  webhook_configs:
    - url: 'http://192.168.56.1:28088/alert-demo/hook/demo'	


啓動後訪問 http://cdh1:9093/ 查看alertmanager 是否啓動成功,

可以通過 status 按鈕,查看alertmanager及其配置:

http://cdh1:9093/#/alerts

在這裏插入圖片描述

4.3prometheus關聯alertmanager

prometheus.yml中的alerting標籤下配置上alertmanager的地址即可,配置如下:

# Alertmanager configuration
alerting:
  alertmanagers:
  - static_configs:
    - targets: ['192.168.199.23:9093']

添加後重啓prometheus即可。

報警通知方式的配置

通知方式一:郵箱報警

一個簡單的 來自互聯網的demo,大致如下:

global:
  #超時時間
  resolve_timeout: 5m
  #smtp地址需要加端口
  smtp_smarthost: 'smtp.126.com:25'
  smtp_from: '[email protected]'
  #發件人郵箱賬號
  smtp_auth_username: '[email protected]'
  #賬號對應的授權碼(不是密碼),阿里雲個人版郵箱目前好像沒有授權碼,126郵箱授權碼可以在“設置”裏面找到
  smtp_auth_password: '1qaz2wsx'
  smtp_require_tls: false

route:
  group_by: ['alertname']
  group_wait: 10s
  group_interval: 1m
  repeat_interval: 4h
  receiver: 'mail'
receivers:
- name: 'mail'
  email_configs:
  - to: '[email protected]'

設置後如果有通知,即可收到郵件如下:
在這裏插入圖片描述

先來看一下alertmanager的配置文件結構

global:
  smtp_smarthost: 'smtp.qq.com:465'
  smtp_from: '[email protected]'
  smtp_auth_username: '[email protected]'
  smtp_auth_password: 'xxxxxxxxx'
  smtp_require_tls: false
route:
  group_by: [alertname]
  group_wait: 5s
  group_interval: 5m
  repeat_interval: 5s
  receiver: default-receiver
receivers:
- name: 'default-receiver'
  email_configs:
  - to: '[email protected]'

通知方式二:使用webhook(java)回調發短信


global:
  resolve_timeout: 5m

route:
  group_by: ['alertname']
  group_wait: 10s
  group_interval: 1m
  repeat_interval: 4h
  receiver: 'webhook'
receivers:
- name: 'webhook'
  webhook_configs:
    - url: 'http://192.168.56.1:28088/alert-demo/hook/demo'	

使用webhook方式,alertmanager調用webhook鉤子地址,發送post請求,

Post請求參數爲json字符串(字符串類型):

{
  "receiver": "webhook",
  "status": "firing",
  "alerts": [
    {
      "status": "firing",
      "labels": {
        "alertname": "DirectMemoryAlert",
        "application": "api-gateway",
        "instance": "192.168.56.1:8888",
        "job": "api-gateway",
        "monitor": "Netty直接內存監控",
        "severity": "page",
        "tip": "根據實際情況調整",
        "version": "1.0.0"
      },
      "annotations": {
        "description": "實例192.168.56.1:8888 直接內存使用超過 5M, (當前值爲: 288)M",
        "summary": "實例 192.168.56.1:8888 直接內存使用超過 5M"
      },
      "startsAt": "2024-03-11T05:51:22.939Z",
      "endsAt": "0001-01-01T00:00:00Z",
      "generatorURL": "http://prometheus:9090/graph?g0.expr=gateway_direct_memory+%3E+5\u0026g0.tab=1",
      "fingerprint": "2e3375fead9bb5fe"
    }
  ],
  "groupLabels": {
    "alertname": "DirectMemoryAlert"
  },
  "commonLabels": {
    "alertname": "DirectMemoryAlert",
    "application": "api-gateway",
    "instance": "192.168.56.1:8888",
    "job": "api-gateway",
    "monitor": "Netty直接內存監控",
    "severity": "page",
    "tip": "根據實際情況調整",
    "version": "1.0.0"
  },
  "commonAnnotations": {
    "description": "實例192.168.56.1:8888 直接內存使用超過 5M, (當前值爲: 288)M",
    "summary": "實例 192.168.56.1:8888 直接內存使用超過 5M"
  },
  "externalURL": "http://alertmanager:9093",
  "version": "4",
  "groupKey": "{}:{alertname=\"DirectMemoryAlert\"}",
  "truncatedAlerts": 0
}

此時需要使用java(其他任何語言都可以,反正只要能處理http的請求就行)搭建個http的請求處理器來處理報警通知,如下:

package com.crazymaker.cloud.alertmanager.demo.controller;

import com.crazymaker.springcloud.common.util.JsonUtil;
import com.crazymaker.springcloud.common.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@RestController
@RequestMapping("/hook")
@Slf4j
public class AlertManagerDemoController {


    public static final Map<String, Object> ALERT_FAIL = new HashMap<>();
    public static final Map<String, Object> ALERT_SUCCESS = new HashMap<>();

    static {
        ALERT_FAIL.put("msg", "報警失敗");
        ALERT_FAIL.put("code", 0);
        ALERT_SUCCESS.put("msg", "報警成功");
        ALERT_SUCCESS.put("code", 1);
    }


    @RequestMapping(value = "/demo", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public String pstn(@RequestBody String json) {
        log.debug("alert notify  params: {}", json);

        if (StringUtils.isBlank(json)) {
            return JsonUtil.pojoToJson(ALERT_FAIL);//告警發送失敗
        }
        Map<String, Object> jo = JsonUtil.jsonToMap(json);

        //獲取 標籤
        Map<String, Object> annotations = (Map<String, Object>) jo.get("commonAnnotations");

        if (annotations == null) {
            return JsonUtil.pojoToJson(ALERT_FAIL);//告警發送失敗
        }


        Object status = jo.get("status");
        Object subject = annotations.get("summary");
        Object content = annotations.get("description");
        log.error("status: {}", status);
        log.error("summary: {}", subject);
        log.error("content: {}", content);

        //開發發送短信
        List<String> users = getRelatedPerson();

        try {
            boolean success = sendMsg(subject, content, users);
            if (success) {
                return JsonUtil.pojoToJson(ALERT_SUCCESS);//告警發送成功
            }
        } catch (Exception e) {
            log.error("=alert sms notify error. json={}", json, e);
        }
        return JsonUtil.pojoToJson(ALERT_FAIL);//告警發送失敗

    }
    //todo  發送短信

    private boolean sendMsg(Object subject, Object content, List<String> users) {
        return true;
    }


    //todo  從配置中心,加載短信號碼
    private List<String> getRelatedPerson() {
        return Collections.emptyList();
    }


}


在這裏插入圖片描述

5.prometheus+alertmanager 實現監控預警總結

回顧一下,時間相關參數

參數名稱 說明 默認值 參數所屬
scrape_interval 指標數據採集間隔 1分鐘 prometheus.yml
evaluation_interval 規則的計算間隔 1分鐘 prometheus.yml
for: 時間 異常持續多長時間發送告警 0 規則配置
group_wait 分組等待時間。同一分組內收到第一個告警等待多久開始發送,目的是爲了同組消息同時發送 30秒 alertmanager.yml
group_interval 上下兩組發送告警的間隔時間。第一次告警發出後等待group_interval時間,開始爲該組觸發新告警 5分鐘 alertmanager.yml
repeat_interval 重發間隔。告警已經發送,且無新增告警,再次發送告警需要的間隔時間 4小時 alertmanager.yml

alertmanager配置功能確認很強大,完全能夠按照自己的目標定義靈活的通知和報警方式,尤其是對webhook的支持,簡直不能更靈活了。

而且alertmanager還支持定義template來更清晰的彰顯要通知的內容。

但是本人還沒有發現alertmanager該怎麼進行配置的熱加載,後面還要再研究下怎麼優化通知,避免告警轟炸和提高告警的準確性。

參考文獻:

https://prometheus.io/download/

說在最後:有問題找老架構取經

怎麼做 指標的治理?

怎麼做監控預警?

以上的內容,如果大家能對答如流,如數家珍,基本上 面試官會被你 震驚到、吸引到。

最終,讓面試官愛到 “不能自已、口水直流”。offer, 也就來了。

在面試之前,建議大家系統化的刷一波 5000頁《尼恩Java面試寶典PDF》,裏邊有大量的大廠真題、面試難題、架構難題。很多小夥伴刷完後, 吊打面試官, 大廠橫着走。

在刷題過程中,如果有啥問題,大家可以來 找 40歲老架構師尼恩交流。

另外,如果沒有面試機會,可以找尼恩來改簡歷、做幫扶。

遇到職業難題,找老架構取經, 可以省去太多的折騰,省去太多的彎路。

尼恩指導了大量的小夥伴上岸,前段時間,剛指導一個40歲+被裁小夥伴,拿到了一個年薪100W的offer。

狠狠卷,實現 “offer自由” 很容易的, 前段時間一個武漢的跟着尼恩捲了2年的小夥伴, 在極度嚴寒/痛苦被裁的環境下, offer拿到手軟, 實現真正的 “offer自由” 。

技術自由的實現路徑:

實現你的 架構自由:

喫透8圖1模板,人人可以做架構

10Wqps評論中臺,如何架構?B站是這麼做的!!!

阿里二面:千萬級、億級數據,如何性能優化? 教科書級 答案來了

峯值21WQps、億級DAU,小遊戲《羊了個羊》是怎麼架構的?

100億級訂單怎麼調度,來一個大廠的極品方案

2個大廠 100億級 超大流量 紅包 架構方案

… 更多架構文章,正在添加中

實現你的 響應式 自由:

響應式聖經:10W字,實現Spring響應式編程自由

這是老版本 《Flux、Mono、Reactor 實戰(史上最全)

實現你的 spring cloud 自由:

Spring cloud Alibaba 學習聖經》 PDF

分庫分表 Sharding-JDBC 底層原理、核心實戰(史上最全)

一文搞定:SpringBoot、SLF4j、Log4j、Logback、Netty之間混亂關係(史上最全)

實現你的 linux 自由:

Linux命令大全:2W多字,一次實現Linux自由

實現你的 網絡 自由:

TCP協議詳解 (史上最全)

網絡三張表:ARP表, MAC表, 路由表,實現你的網絡自由!!

實現你的 分佈式鎖 自由:

Redis分佈式鎖(圖解 - 秒懂 - 史上最全)

Zookeeper 分佈式鎖 - 圖解 - 秒懂

實現你的 王者組件 自由:

隊列之王: Disruptor 原理、架構、源碼 一文穿透

緩存之王:Caffeine 源碼、架構、原理(史上最全,10W字 超級長文)

緩存之王:Caffeine 的使用(史上最全)

Java Agent 探針、字節碼增強 ByteBuddy(史上最全)

實現你的 面試題 自由:

4800頁《尼恩Java面試寶典 》 40個專題

免費獲取11個技術聖經PDF:

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