簡介
Prometheus 是一套開源的系統監控報警框架。它啟發於 Google 的 borgmon 監控系統,由工作在 SoundCloud 的 google 前員工在 2012 年建立,作為社群開源專案進行開發,並於 2015 年正式釋出。
特點
作為新一代的監控框架,Prometheus 具有以下特點:
- 強大的多維度資料模型:
- 時間序列資料通過 metric 名和鍵值對來區分。
- 所有的 metrics 都可以設定任意的多維標籤。
- 資料模型更隨意,不需要刻意設定為以點分隔的字串。
- 可以對資料模型進行聚合,切割和切片操作。
- 支援雙精度浮點型別,標籤可以設為全 unicode。
- 靈活而強大的查詢語句(PromQL):在同一個查詢語句,可以對多個 metrics 進行乘法、加法、連線、取分數位等操作。
- 易於管理: Prometheus server 是一個單獨的二進位制檔案,可直接在本地工作,不依賴於分散式儲存。
- 高效:平均每個取樣點僅佔 3.5 bytes,且一個 Prometheus server 可以處理數百萬的 metrics。
使用 pull 模式採集時間序列資料,這樣不僅有利於本機測試而且可以避免有問題的伺服器推送壞的 metrics。 - 可以採用 push gateway 的方式把時間序列資料推送至 Prometheus server 端。
- 可以通過服務發現或者靜態配置去獲取監控的 targets。
- 有多種視覺化圖形介面。
- 易於伸縮。
組成及架構
Prometheus 生態圈中包含了多個元件,其中許多元件是可選的:
- Prometheus Server: 用於收集和儲存時間序列資料。
- Client Library: 客戶端庫,為需要監控的服務生成相應的 metrics 並暴露給 Prometheus server。當 Prometheus server 來 pull 時,直接返回實時狀態的 metrics。
- Push Gateway: 主要用於短期的 jobs。由於這類 jobs 存在時間較短,可能在 Prometheus 來 pull 之前就消失了。為此,這次 jobs 可以直接向 Prometheus server 端推送它們的 metrics。這種方式主要用於服務層面的 metrics,對於機器層面的 metrices,需要使用 node exporter。
- Exporters: 用於暴露已有的第三方服務的 metrics 給 Prometheus。
- Alertmanager: 從 Prometheus server 端接收到 alerts 後,會進行去除重複資料,分組,並路由到對收的接受方式,發出報警。常見的接收方式有:電子郵件,pagerduty,OpsGenie, webhook 等。
- 一些其他的工具。
下圖為 Prometheus 官方文件中的架構圖:
從上圖可以看出,Prometheus 的主要模組包括:Prometheus server, exporters, Pushgateway, PromQL, Alertmanager 以及圖形介面。
其大概的工作流程是:
- Prometheus server 定期從配置好的 jobs 或者 exporters 中拉 metrics,或者接收來自Pushgateway 發過來的 metrics,或者從其他的 Prometheus server 中拉 metrics。
- Prometheus server 在本地儲存收集到的 metrics,並執行已定義好的 alert.rules,記錄新的時間序列或者向 Alertmanager 推送警報。
- Alertmanager 根據配置檔案,對接收到的警報進行處理,發出告警。
在圖形介面中,視覺化採集資料。
相關概念
下面將對 Prometheus 中的資料模型(時間序列),metric 型別,instance 和 jobs等概念進行介紹。
資料模型
Prometheus 中儲存的資料為時間序列,是由 metric 的名字和一系列的標籤(鍵值對)唯一標識的,不同的標籤則代表不同的時間序列。
- metric 名字:該名字應該具有語義,一般用於表示 metric 的功能,例如:http_requests_ total, 表示 http 請求的總數。其中,metric 名字由 ASCII 字元,數字,下劃線,以及冒號組成,且必須滿足正規表示式 [a-zA-Z_:][a-zA-Z0-9_:]*。
- 標籤:使同一個時間序列有了不同維度的識別。例如 http_requests_total{method="Get"} 表示所有 http 請求中的 Get 請求。當 method="post" 時,則為新的一個 metric。標籤中的鍵由 ASCII 字元,數字,以及下劃線組成,且必須滿足正規表示式 [a-zA-Z_:][a-zA-Z0-9_:]*。
- 樣本:實際的時間序列,每個序列包括一個 float64 的值和一個毫秒級的時間戳。
- 格式:
{
Metrics種類
Prometheus客戶端庫提供了四種核心Metrics型別。
Counter(計數器)
- 說明:Counter是一個累積度量,它表示一個單調遞增的 Metrics,其值只能在重啟時遞增或重置為零
- 場景:可以使用Counter來表示http的請求數、已完成的任務數或錯誤數、下單數。
Gauge(測量儀)
- 說明:當前值的一次快照(snapshot)測量,可增可減。
- 場景:磁碟使用率,當前同時線上使用者數。
Histogram(直方圖)
- 說明:通過區間統計樣本分佈。
- 場景:請求延遲時間的統計。例如統計 0~200ms、200ms~400ms、400ms~800ms 區間的請求數有多。
Summary(彙總)
- 說明:根據樣本統計出百分位。
- 場景:請求延遲時間的統計。例如統計 95%的請求延遲 < xxx ms ,99%的請求延遲 < xxx ms
instance 和 jobs
在Prometheus術語中,你可以scrape(刮擦)的端點稱為 例項,通常對應於單個程式。一組同種型別的 instances(主要用於保證可擴充套件性和可靠性),例如:具有四個複製instances(例項)的API伺服器job作業:
- job: api-server
- instance 1: 1.2.3.4:5670
- instance 2: 1.2.3.4:5671
- instance 3: 5.6.7.8:5670
- instance 4: 5.6.7.8:5671
當Prometheus scrape(刮擦)目標時,它會自動在scrape的時間序列上附加一些標籤,用來識別scrape的目標。
- job:目標所屬的已配置job名稱。
- instance:
: 已刮擦的目標URL 的一部分。
對於每次例項 scrape(刮取,Prometheus都會在以下時間序列中儲存樣本:
- up{job="<job-name>", instance="<instance-id>"}:1如果例項是健康的,即可達,或者0刮擦失敗。
- scrape_duration_seconds{job="<job-name>", instance="<instance-id>"}:刮擦持續時間。
- scrape_samples_post_metric_relabeling{job="<job-name>", instance="<instance-id>"}:應用度量標準重新標記後剩餘的樣本數。
- scrape_samples_scraped{job="<job-name>", instance="<instance-id>"}:目標暴露的樣本數。
- scrape_series_added{job="<job-name>", instance="<instance-id>"}:該刮擦中新系列的大致數量。v2.10中的新功能。
up時間序列對於例項可用性監視非常有用。
安裝和配置
安裝
你可以在官網 https://prometheus.io/download/ 下載 安裝包,解壓後使用。為了方便,我使用docker 映象的方式 執行Prometheus。
docker run --name prometheus -d -p 9090:9090 prom/prometheus
瀏覽器輸入http://localhost:9090 ,訪問 Prometheus 的 Web UI:
點選選單欄 “Status” 下的 Targets ,介面如下:
可以看大Prometheus 自身 metrics 處於UP狀態 ,說明 安裝成功。
配置
Prometheus 的配置檔案 prometheus.yml 內容如下:
# 全域性設定,可以被覆蓋
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
# - "first.rules"
# - "second.rules"
scrape_configs:
- job_name: prometheus
static_configs:
- targets: ['localhost:9090']
該global
塊控制 Prometheus 的全域性配置。我們有兩種選擇。第一個,scrape_interval
控制Prometheus 刮擦目標的頻率。你可以為單個目標覆蓋此值。在這種情況下,全域性設定是每15秒刮一次。該evaluation_interval
選項控制普羅米修斯評估規則的頻率。Prometheus 使用規則建立新的時間序列並生成警報。
該rule_files
塊指定我們希望 Prometheus 載入的任何規則的位置。現在我們沒有規則。
最後一個塊scrape_configs
控制 Prometheus 監視的資源。由於 Prometheus 還將自己的資料公開為HTTP端點,因此它可以抓取並監控自身的健康狀況。在預設配置中有一個名為 prometheus 的job,它抓取 prometheus 伺服器 公開的時間序列資料。該作業包含一個靜態配置的目標,即埠9090上的本地主機。返回的時間序列資料將詳細說明Prometheus伺服器的狀態和效能。
實驗
Prometheus HTTP 度量模擬器
為了演示 Prometheus 的簡單使用,這裡執行一個 Prometheus HTTP 度量模擬器。模擬一個簡單的HTTP微服務,生成Prometheus Metrics,通過 docker 執行。
docker run -p 8080:8080 pierrevincent/prom-http-simulator:0.1
它在/metrics端點下公開以下Prometheus指標:
- http_requests_total:請求計數器,標籤endpoint和status
- http_request_duration_milliseconds:請求延遲直方圖
可以開啟流量高峰模式,更改流量高峰模式可以通過以下方式完成:
# ON
curl -X POST http://127.0.0.1:8080/spike/on
# OFF
curl -X POST http://127.0.0.1:8080/spike/off
# RANDOM
curl -X POST http://127.0.0.1:8080/spike/random
錯誤率預設為1%。它可以更改為0到100之間的數字:
# 例如將錯誤率設定為50%
curl -H 'Content-Type: application/json' -X PUT -d '{"error_rate": 50}' http://127.0.0.1:8080/error_rate
修改Prometheus配置
需要將 HTTP 度量模擬器 的 metrics端點 配置到 Prometheus的配置檔案 prometheus.yml 中。
建立一個 prometheus.yml 檔案 內容如下:
global:
scrape_interval: 5s
evaluation_interval: 5s
scrape_timeout: 5s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'http-simulator'
metrics_path: /metrics
static_configs:
- targets: ['172.16.1.232:8080']
通過docker up
命令替換 容器中的配置檔案:
docker cp prometheus.yml prometheus:/etc/prometheus/
重啟容器:
docker restart prometheus
訪問 http://localhost:9090/targets ,發現已經出現了 target “http-simulator” ,並且為UP狀態。
查詢
請求率(Request Rate)查詢
查詢http請求數
http_requests_total{job="http-simulator"}
查詢成功login請求數
http_requests_total{job="http-simulator", status="200", endpoint="/login"}
查詢成功請求數,以endpoint區分
http_requests_total{job="http-simulator", status="200"}
查詢總成功請求數
sum(http_requests_total{job="http-simulator", status="200"})
查詢成功請求率,以endpoint區分
rate(http_requests_total{job="http-simulator", status="200"}[5m])
查詢總成功請求率
sum(rate(http_requests_total{job="http-simulator", status="200"}[5m]))
延遲分佈(Latency distribution)查詢
查詢http-simulator延遲分佈
http_request_duration_milliseconds_bucket{job="http-simulator"}
查詢成功login延遲分佈
http_request_duration_milliseconds_bucket{job="http-simulator", status="200", endpoint="/login"}
不超過200ms延遲的成功login請求佔比
sum(http_request_duration_milliseconds_bucket{job="http-simulator", status="200", endpoint="/login", le="200"}) / sum(http_request_duration_milliseconds_count{job="http-simulator", status="200", endpoint="/login"})
成功login請求延遲的99百分位
histogram_quantile(0.99, rate(http_request_duration_milliseconds_bucket{job="http-simulator", status="200", endpoint="/login"}[5m]))
上面給出的這些查詢表示式,在 prometheus 的 查詢介面上自行測試下 ,這裡就不一一測試了,
總結
本篇對 Prometheus 的組成,架構和基本概念進行了介紹,並例項演示了 Prometheus 的查詢表示式的應用。本篇是 Prometheus 系列的第一篇, 後續還會有Prometheus與其他圖形介面的整合,與 springboot 應用的整合等 。
參考
https://prometheus.io/docs/introduction/overview/
https://www.ibm.com/developerworks/cn/cloud/library/cl-lo-prometheus-getting-started-and-practice/index.html
歡迎掃碼或微信搜尋公眾號《程式設計師果果》關注我,關注有驚喜~