簡(jiǎn)介
Prometheus 是一套開源的系統(tǒng)監(jiān)控報(bào)警框架。它啟發(fā)于 Google 的 borgmon 監(jiān)控系統(tǒng),由工作在 SoundCloud 的 google 前員工在 2012 年創(chuàng)建,作為社區(qū)開源項(xiàng)目進(jìn)行開發(fā),并于 2015 年正式發(fā)布。
特點(diǎn)
作為新一代的監(jiān)控框架,Prometheus 具有以下特點(diǎn):
- 強(qiáng)大的多維度數(shù)據(jù)模型:
- 時(shí)間序列數(shù)據(jù)通過(guò) metric 名和鍵值對(duì)來(lái)區(qū)分。
- 所有的 metrics 都可以設(shè)置任意的多維標(biāo)簽。
- 數(shù)據(jù)模型更隨意,不需要刻意設(shè)置為以點(diǎn)分隔的字符串。
- 可以對(duì)數(shù)據(jù)模型進(jìn)行聚合,切割和切片操作。
- 支持雙精度浮點(diǎn)類型,標(biāo)簽可以設(shè)為全 unicode。
- 靈活而強(qiáng)大的查詢語(yǔ)句(PromQL):在同一個(gè)查詢語(yǔ)句,可以對(duì)多個(gè) metrics 進(jìn)行乘法、加法、連接、取分?jǐn)?shù)位等操作。
- 易于管理: Prometheus server 是一個(gè)單獨(dú)的二進(jìn)制文件,可直接在本地工作,不依賴于分布式存儲(chǔ)。
- 高效:平均每個(gè)采樣點(diǎn)僅占 3.5 bytes,且一個(gè) Prometheus server 可以處理數(shù)百萬(wàn)的 metrics。
使用 pull 模式采集時(shí)間序列數(shù)據(jù),這樣不僅有利于本機(jī)測(cè)試而且可以避免有問(wèn)題的服務(wù)器推送壞的 metrics。 - 可以采用 push gateway 的方式把時(shí)間序列數(shù)據(jù)推送至 Prometheus server 端。
- 可以通過(guò)服務(wù)發(fā)現(xiàn)或者靜態(tài)配置去獲取監(jiān)控的 targets。
- 有多種可視化圖形界面。
- 易于伸縮。
組成及架構(gòu)
Prometheus 生態(tài)圈中包含了多個(gè)組件,其中許多組件是可選的:
- Prometheus Server: 用于收集和存儲(chǔ)時(shí)間序列數(shù)據(jù)。
- Client Library: 客戶端庫(kù),為需要監(jiān)控的服務(wù)生成相應(yīng)的 metrics 并暴露給 Prometheus server。當(dāng) Prometheus server 來(lái) pull 時(shí),直接返回實(shí)時(shí)狀態(tài)的 metrics。
- Push Gateway: 主要用于短期的 jobs。由于這類 jobs 存在時(shí)間較短,可能在 Prometheus 來(lái) pull 之前就消失了。為此,這次 jobs 可以直接向 Prometheus server 端推送它們的 metrics。這種方式主要用于服務(wù)層面的 metrics,對(duì)于機(jī)器層面的 metrices,需要使用 node exporter。
- Exporters: 用于暴露已有的第三方服務(wù)的 metrics 給 Prometheus。
- Alertmanager: 從 Prometheus server 端接收到 alerts 后,會(huì)進(jìn)行去除重復(fù)數(shù)據(jù),分組,并路由到對(duì)收的接受方式,發(fā)出報(bào)警。常見(jiàn)的接收方式有:電子郵件,pagerduty,OpsGenie, webhook 等。
- 一些其他的工具。
下圖為 Prometheus 官方文檔中的架構(gòu)圖:

從上圖可以看出,Prometheus 的主要模塊包括:Prometheus server, exporters, Pushgateway, PromQL, Alertmanager 以及圖形界面。
其大概的工作流程是:
- Prometheus server 定期從配置好的 jobs 或者 exporters 中拉 metrics,或者接收來(lái)自Pushgateway 發(fā)過(guò)來(lái)的 metrics,或者從其他的 Prometheus server 中拉 metrics。
- Prometheus server 在本地存儲(chǔ)收集到的 metrics,并運(yùn)行已定義好的 alert.rules,記錄新的時(shí)間序列或者向 Alertmanager 推送警報(bào)。
- Alertmanager 根據(jù)配置文件,對(duì)接收到的警報(bào)進(jìn)行處理,發(fā)出告警。
在圖形界面中,可視化采集數(shù)據(jù)。
相關(guān)概念
下面將對(duì) Prometheus 中的數(shù)據(jù)模型(時(shí)間序列),metric 類型,instance 和 jobs等概念進(jìn)行介紹。
數(shù)據(jù)模型
Prometheus 中存儲(chǔ)的數(shù)據(jù)為時(shí)間序列,是由 metric 的名字和一系列的標(biāo)簽(鍵值對(duì))唯一標(biāo)識(shí)的,不同的標(biāo)簽則代表不同的時(shí)間序列。
- metric 名字:該名字應(yīng)該具有語(yǔ)義,一般用于表示 metric 的功能,例如:http_requests_ total, 表示 http 請(qǐng)求的總數(shù)。其中,metric 名字由 ASCII 字符,數(shù)字,下劃線,以及冒號(hào)組成,且必須滿足正則表達(dá)式 [a-zA-Z_:][a-zA-Z0-9_:]*。
- 標(biāo)簽:使同一個(gè)時(shí)間序列有了不同維度的識(shí)別。例如 http_requests_total{method="Get"} 表示所有 http 請(qǐng)求中的 Get 請(qǐng)求。當(dāng) method="post" 時(shí),則為新的一個(gè) metric。標(biāo)簽中的鍵由 ASCII 字符,數(shù)字,以及下劃線組成,且必須滿足正則表達(dá)式 [a-zA-Z_:][a-zA-Z0-9_:]*。
- 樣本:實(shí)際的時(shí)間序列,每個(gè)序列包括一個(gè) float64 的值和一個(gè)毫秒級(jí)的時(shí)間戳。
- 格式:<metric name>{<label name>=<label value>, …},例如:http_requests_total{method="POST",endpoint="/api/tracks"}。
Metrics種類
Prometheus客戶端庫(kù)提供了四種核心Metrics類型。
Counter(計(jì)數(shù)器)
- 說(shuō)明:Counter是一個(gè)累積度量,它表示一個(gè)單調(diào)遞增的 Metrics,其值只能在重啟時(shí)遞增或重置為零
- 場(chǎng)景:可以使用Counter來(lái)表示http的請(qǐng)求數(shù)、已完成的任務(wù)數(shù)或錯(cuò)誤數(shù)、下單數(shù)。
Gauge(測(cè)量?jī)x)
- 說(shuō)明:當(dāng)前值的一次快照(snapshot)測(cè)量,可增可減。
- 場(chǎng)景:磁盤使用率,當(dāng)前同時(shí)在線用戶數(shù)。
Histogram(直方圖)
- 說(shuō)明:通過(guò)區(qū)間統(tǒng)計(jì)樣本分布。
- 場(chǎng)景:請(qǐng)求延遲時(shí)間的統(tǒng)計(jì)。例如統(tǒng)計(jì) 0200ms、200ms400ms、400ms~800ms 區(qū)間的請(qǐng)求數(shù)有多。
Summary(匯總)
- 說(shuō)明:根據(jù)樣本統(tǒng)計(jì)出百分位。
- 場(chǎng)景:請(qǐng)求延遲時(shí)間的統(tǒng)計(jì)。例如統(tǒng)計(jì) 95%的請(qǐng)求延遲 < xxx ms ,99%的請(qǐng)求延遲 < xxx ms
instance 和 jobs
在Prometheus術(shù)語(yǔ)中,你可以scrape(刮擦)的端點(diǎn)稱為 實(shí)例,通常對(duì)應(yīng)于單個(gè)進(jìn)程。一組同種類型的 instances(主要用于保證可擴(kuò)展性和可靠性),例如:具有四個(gè)復(fù)制instances(實(shí)例)的API服務(wù)器job作業(yè):
- 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
當(dāng)Prometheus scrape(刮擦)目標(biāo)時(shí),它會(huì)自動(dòng)在scrape的時(shí)間序列上附加一些標(biāo)簽,用來(lái)識(shí)別scrape的目標(biāo)。
- job:目標(biāo)所屬的已配置job名稱。
- instance:<host>:<port>已刮擦的目標(biāo)URL 的一部分。
對(duì)于每次實(shí)例 scrape(刮取,Prometheus都會(huì)在以下時(shí)間序列中存儲(chǔ)樣本:
- up{job="<job-name>", instance="<instance-id>"}:1如果實(shí)例是健康的,即可達(dá),或者0刮擦失敗。
- scrape_duration_seconds{job="<job-name>", instance="<instance-id>"}:刮擦持續(xù)時(shí)間。
- scrape_samples_post_metric_relabeling{job="<job-name>", instance="<instance-id>"}:應(yīng)用度量標(biāo)準(zhǔn)重新標(biāo)記后剩余的樣本數(shù)。
- scrape_samples_scraped{job="<job-name>", instance="<instance-id>"}:目標(biāo)暴露的樣本數(shù)。
- scrape_series_added{job="<job-name>", instance="<instance-id>"}:該刮擦中新系列的大致數(shù)量。v2.10中的新功能。
up時(shí)間序列對(duì)于實(shí)例可用性監(jiān)視非常有用。
安裝和配置
安裝
你可以在官網(wǎng) https://prometheus.io/download/ 下載 安裝包,解壓后使用。為了方便,我使用docker 鏡像的方式 運(yùn)行Prometheus。
docker run --name prometheus -d -p 9090:9090 prom/prometheus
瀏覽器輸入http://localhost:9090 ,訪問(wèn) Prometheus 的 Web UI:

點(diǎn)擊菜單欄 “Status” 下的 Targets ,界面如下:

可以看大Prometheus 自身 metrics 處于UP狀態(tài) ,說(shuō)明 安裝成功。
配置
Prometheus 的配置文件 prometheus.yml 內(nèi)容如下:
# 全局設(shè)置,可以被覆蓋
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 的全局配置。我們有兩種選擇。第一個(gè),scrape_interval控制Prometheus 刮擦目標(biāo)的頻率。你可以為單個(gè)目標(biāo)覆蓋此值。在這種情況下,全局設(shè)置是每15秒刮一次。該evaluation_interval選項(xiàng)控制普羅米修斯評(píng)估規(guī)則的頻率。Prometheus 使用規(guī)則創(chuàng)建新的時(shí)間序列并生成警報(bào)。
該rule_files塊指定我們希望 Prometheus 加載的任何規(guī)則的位置?,F(xiàn)在我們沒(méi)有規(guī)則。
最后一個(gè)塊scrape_configs控制 Prometheus 監(jiān)視的資源。由于 Prometheus 還將自己的數(shù)據(jù)公開為HTTP端點(diǎn),因此它可以抓取并監(jiān)控自身的健康狀況。在默認(rèn)配置中有一個(gè)名為 prometheus 的job,它抓取 prometheus 服務(wù)器 公開的時(shí)間序列數(shù)據(jù)。該作業(yè)包含一個(gè)靜態(tài)配置的目標(biāo),即端口9090上的本地主機(jī)。返回的時(shí)間序列數(shù)據(jù)將詳細(xì)說(shuō)明Prometheus服務(wù)器的狀態(tài)和性能。
實(shí)驗(yàn)
Prometheus HTTP 度量模擬器
為了演示 Prometheus 的簡(jiǎn)單使用,這里運(yùn)行一個(gè) Prometheus HTTP 度量模擬器。模擬一個(gè)簡(jiǎn)單的HTTP微服務(wù),生成Prometheus Metrics,通過(guò) docker 運(yùn)行。
docker run -p 8080:8080 pierrevincent/prom-http-simulator:0.1
它在/metrics端點(diǎn)下公開以下Prometheus指標(biāo):
- http_requests_total:請(qǐng)求計(jì)數(shù)器,標(biāo)簽endpoint和status
- http_request_duration_milliseconds:請(qǐng)求延遲直方圖
可以開啟流量高峰模式,更改流量高峰模式可以通過(guò)以下方式完成:
# 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
錯(cuò)誤率默認(rèn)為1%。它可以更改為0到100之間的數(shù)字:
# 例如將錯(cuò)誤率設(shè)置為50%
curl -H 'Content-Type: application/json' -X PUT -d '{"error_rate": 50}' http://127.0.0.1:8080/error_rate
修改Prometheus配置
需要將 HTTP 度量模擬器 的 metrics端點(diǎn) 配置到 Prometheus的配置文件 prometheus.yml 中。
創(chuàng)建一個(gè) prometheus.yml 文件 內(nèi)容如下:
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']
通過(guò)docker up 命令替換 容器中的配置文件:
docker cp prometheus.yml prometheus:/etc/prometheus/
重啟容器:
docker restart prometheus
訪問(wèn) http://localhost:9090/targets ,發(fā)現(xiàn)已經(jīng)出現(xiàn)了 target “http-simulator” ,并且為UP狀態(tài)。

查詢
請(qǐng)求率(Request Rate)查詢
查詢http請(qǐng)求數(shù)
http_requests_total{job="http-simulator"}

查詢成功login請(qǐng)求數(shù)
http_requests_total{job="http-simulator", status="200", endpoint="/login"}

查詢成功請(qǐng)求數(shù),以endpoint區(qū)分
http_requests_total{job="http-simulator", status="200"}
查詢總成功請(qǐng)求數(shù)
sum(http_requests_total{job="http-simulator", status="200"})
查詢成功請(qǐng)求率,以endpoint區(qū)分
rate(http_requests_total{job="http-simulator", status="200"}[5m])
查詢總成功請(qǐng)求率
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"}
不超過(guò)200ms延遲的成功login請(qǐng)求占比
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請(qǐng)求延遲的99百分位
histogram_quantile(0.99, rate(http_request_duration_milliseconds_bucket{job="http-simulator", status="200", endpoint="/login"}[5m]))
上面給出的這些查詢表達(dá)式,在 prometheus 的 查詢界面上自行測(cè)試下 ,這里就不一一測(cè)試了,
總結(jié)
本篇對(duì) Prometheus 的組成,架構(gòu)和基本概念進(jìn)行了介紹,并實(shí)例演示了 Prometheus 的查詢表達(dá)式的應(yīng)用。本篇是 Prometheus 系列的第一篇, 后續(xù)還會(huì)有Prometheus與其他圖形界面的集成,與 springboot 應(yīng)用的集成等 。
參考
https://prometheus.io/docs/introduction/overview/
https://www.ibm.com/developerworks/cn/cloud/library/cl-lo-prometheus-getting-started-and-practice/index.html
關(guān)注我
