Prometheus(譯:普羅米修斯)用領先的開源監控解決方案為你的名額和警報提供動力(賦能)。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SO4QjN1gTO3ETMtQTMxUzMxQTNxUjM5ATOxAjMtMjN5QzN48CX5ATOxAjMvw1M2kDN3gzLcd2bsJ2Lc12bj5ycn9Gbi52YugTMwIzZtl2Lc9CX6MHc0RHaiojIsJye.png)
1. 概述
1.1. Prometheus是什麼?
Prometheus是一個開源的系統監控和警報工具包。自2012年啟動以來,許多公司群組織都采用了Prometheus,該項目擁有非常活躍的開發人員和使用者社群。它現在是一個獨立的開源項目,獨立于任何公司進行維護。Prometheus于2016年加入雲原生計算基金會,成為繼Kubernetes之後的第二個托管項目。
1.1.1. Prometheus的主要特性:
- 一個多元資料模型,包含由名額名稱和鍵/值對(Tag)辨別的時間序列資料
- PromQL是一種靈活的查詢語音,用于查詢并利用這些次元資料
- 不依賴分布式存儲,單個伺服器節點是自治的
- 時間序列收集是通過HTTP上的pull模型進行的(支援Pull)
- 推送時間序列是通過一個中間網關來支援的(也支援Push)
- 目标是通過服務發現或靜态配置發現的
- 多種模式的圖形和儀表盤支援
總結一下,就是多元資料模型、PromQL查詢語言、節點自治、HTTP主動拉取或者網關主動推送的方式擷取時間序列資料、自動發現目标、多種儀表盤支援
1.1.2. 元件:
- Prometheus server,它負責抓取和存儲時間序列資料,是最主要的元件
- client libraries,用于檢測應用程式代碼的用戶端庫
- push gateway,用于支援短期的jobs
- exporters,用于支援HAProxy等第三方
- alertmanager,用于處理告警
- 各種支援工具
大多數Prometheus元件都是用Go編寫的,這使得它們易于作為靜态二進制檔案建構和部署
1.1.3. 架構:
這張圖展示了架構及其生态系統的一些組成部分:
Prometheus從工具化的作業中擷取名額,要麼直接擷取,要麼通過中介推送網關擷取短期作業。它在本地存儲所有抓取的樣本,并對這些資料應用規則将這些資料進行聚合,并記錄新的時間序列,或者生成警報。可以用Grafana或其他API來可視化收集的資料。
1.2. 什麼時候用它合适
Prometheus可以很好地記錄任何純數字時間序列。它既适合以機器為中心的監視,也适合高度動态的面向服務的體系結構的監視。在微服務的世界中,它對多元資料收集和查詢的支援是一個特别的優勢。
Prometheus是為可靠性而設計的,在你的服務當機的時候,你可以快速診斷問題。每台Prometheus伺服器都是獨立的,不依賴于網絡存儲或其他遠端服務。
1.3. 什麼時候用它不合适
Prometheus的值的可靠性。你總是可以檢視有關系統的統計資訊,即使在出現故障的情況下也是如此。如果你需要100%的準确性,例如按請求計費,Prometheus不是一個好的選擇,因為收集的資料可能不夠詳細和完整。在這種情況下,最好使用其他系統來收集和分析用于計費的資料,并使用Prometheus來完成剩下的監視工作。
1.4. Prometheus VS InfluxDB
InfluxDB是一個開源的時間序列資料庫,具有擴充和叢集的商業選項。InfluxDB項目是在Prometheus開發開始将近一年後釋出的,是以當時無法考慮将其作為替代方案。盡管如此,Prometheus和fluxdb之間仍然存在顯著的差異。二者有許多相似之處。兩者都有标簽(在InfluxDB中稱為tags)來有效地支援多元度度量。它們基本上使用相同的資料壓縮算法。兩者都具有廣泛的內建,包括彼此之間的內建。兩者都有挂鈎,允許進一步擴充它們,例如在統計工具中分析資料或執行自動化操作。
下列情況,用InfluxDB更好:
- 如果你正在進行事件日志記錄
- 商業選項為InfluxDB提供叢集,這對于長期資料存儲也更好
- 最終實作副本之間資料的一緻性
下列情況,用Prometheus更好:
- 如果你主要做的是度量
- 如果你需要更強大的查詢語言、警報和通知功能
- 更高的可用性和正常運作時間,用于繪圖和報警
InfluxDB由一家遵循開放核心模型的商業公司維護,提供進階特性,如閉源叢集、托管和支援。
Prometheus是一個完全開源和獨立的項目,由許多公司和個人維護,其中一些還提供商業服務和支援。
2. 基本概念
2.1. 資料模型
Prometheus基本上将所有資料存儲為時間序列:屬于同一名額和同一組标記次元的時間戳值流。除了存儲時間序列外,Prometheus還可以根據查詢結果生成臨時派生的時間序列。
(PS:這裡對時間序列的解釋是這樣的,
time series: streams of timestamped values belonging to the same metric and the same set of labeled dimensions
)
2.1.1. Metric names and labels
Every time series is uniquely identified by its metric name and optional key-value pairs called labels.
(每個時間序列都由其名額名稱和稱為标簽的可選鍵值對唯一辨別)
名額名稱指定要度量的系統的一般特性(例如,http_requests_total表示接收的HTTP請求的總數)。它可能包含ASCII字母和數字,以及下劃線和冒号。它必須比對正規表達式[a-zA-Z_:][a-zA-Z0-9_:]*
标簽名稱可以包含ASCII字母、數字和下劃線。它們必須比對正規表達式[a-zA-Z_][a-zA-Z0-9_]*。以__開頭的标簽名稱保留内部使用。
标簽值可以包含任何Unicode字元。
2.1.2. Sample(樣本)
樣本構成實際的時間序列資料。每個樣本包括:
- a float64 value
- a millisecond-precision timestamp
2.1.3. notation(記法)
給定一個度量名稱和一組标簽,時間序列通常使用以下符号辨別:
<metric name>{<label name>=<label value>,...}
例如,有這樣一個時間序列,名額名稱是api_http_requests_total,有兩個标簽method="POST"和handler="/messages",那麼這個時間序列可以這樣寫:
api_http_requests_total{method="POST", handler="/messages"}
2.2. metric types(名額類型)
2.2.1. Counter(計數器)
計數器是一個累積名額,它表示一個單調遞增的計數器,其值隻能在重新開機時遞增或重置為零。例如,可以使用計數器來表示已服務的請求數、已完成的任務數或錯誤數。不要使用計數器來反映一個可能會減小的值。例如,不要使用計數器表示目前正在運作的程序的數量,這種情況下,你應該用gauge。
2.2.2. Gauge(計量器)
計量器表示一個可以任意上下移動的數值。
計量器通常用于測量溫度或目前記憶體使用量等,也用于“計數”,比如并發請求的數量。
2.2.3. Histogram(直方圖、柱狀圖)
直方圖對觀察結果(通常是請求持續時間或響應大小之類的東西)進行采樣,并在可配置的桶中計數。它還提供了所有觀測值的和。
直方圖用一個基本的名額名<basename>暴露在一個抓取期間的多個時間序列:
- 觀察桶的累積計數器,格式為<basename>_bucket{le="<upper inclusive bound>"}
- 所有觀測值的總和,格式為<basename>_sum
- 已觀察到的事件的計數,格式為<basename>_count
2.2.4. Summary(摘要)
與柱狀圖類似,摘要樣例觀察結果(通常是請求持續時間和響應大小之類的内容)。雖然它還提供了觀測值的總數和所有觀測值的總和,但它計算了一個滑動時間視窗上的可配置分位數。
2.3. Jobs AND Instances(作業與執行個體)
在Prometheus的術語中,可以抓取的端點稱為執行個體,通常對應于單個程序。具有相同目的的執行個體集合稱為作業。
例如,一個API Server job 有4個副本instances:
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
2.3.1. 自動生成标簽和時間序列
當Prometheus抓取目标時,它會自動在抓取的時間序列上附加一些标簽,用來識别被抓取的目标:
- job:目标所屬的已配置作業名稱
- instance:<host>:<port>是被抓取的目标URL的一部分
3. 快速開始
Prometheus是一個開源的系統監控和警報工具包,具有活躍的生态系統。
3.1. 下載下傳與安裝
Prometheus是一個監控平台,它通過抓取這些目标上的HTTP端點來收集被監控目标的名額。
需要下載下傳、安裝并運作Prometheus。還需要下載下傳并安裝一個exporter,它是将主機和服務上的時間序列資料導出的工具。
https://prometheus.io/download/
在運作Prometheus之前,我們先配置一下
3.1.1. 配置Prometheus監視它自己
Prometheus通過抓取目标上的HTTP端點資料來從被監控的目标收集資料。由于Prometheus也以同樣的方式公開自己的資料,是以它還可以抓取和監測自己的健康狀況。
雖然Prometheus伺服器在實踐中隻收集關于自己的資料不是很有用,但是它是一個很好的開始示例。将以下基本的Prometheus配置儲存為一個名為Prometheus.yml的檔案:
1 global:
2 scrape_interval: 15s # By default, scrape targets every 15 seconds.
3
4 # Attach these labels to any time series or alerts when communicating with
5 # external systems (federation, remote storage, Alertmanager).
6 external_labels:
7 monitor: 'codelab-monitor'
8
9 # A scrape configuration containing exactly one endpoint to scrape:
10 # Here it's Prometheus itself.
11 scrape_configs:
12 # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
13 - job_name: 'prometheus'
14
15 # Override the global default and scrape targets from this job every 5 seconds.
16 scrape_interval: 5s
17
18 static_configs:
19 - targets: ['localhost:9090']
3.1.2. 啟動Prometheus
1 # Start Prometheus.
2 # By default, Prometheus stores its database in ./data (flag --storage.tsdb.path).
3 ./prometheus --config.file=prometheus.yml
3.2. 配置
Prometheus可以通過指令行和配置檔案進行配置。配置檔案定義了與抓取作業及其執行個體相關的所有内容,以及要加載哪些規則檔案。
運作./prometheus -h可以檢視所有支援的指令
為了指定要加載哪個配置檔案,請使用--config選項
配置檔案是YAML格式的
配置項太多,不一一列舉,自行檢視
https://prometheus.io/docs/prometheus/latest/configuration/configuration/
global:
# How frequently to scrape targets by default.
[ scrape_interval: <duration> | default = 1m ]
# How long until a scrape request times out.
[ scrape_timeout: <duration> | default = 10s ]
# How frequently to evaluate rules.
[ evaluation_interval: <duration> | default = 1m ]
# The labels to add to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
external_labels:
[ <labelname>: <labelvalue> ... ]
# Rule files specifies a list of globs. Rules and alerts are read from
# all matching files.
rule_files:
[ - <filepath_glob> ... ]
# A list of scrape configurations.
scrape_configs:
[ - <scrape_config> ... ]
# Alerting specifies settings related to the Alertmanager.
alerting:
alert_relabel_configs:
[ - <relabel_config> ... ]
alertmanagers:
[ - <alertmanager_config> ... ]
# Settings related to the remote write feature.
remote_write:
[ - <remote_write> ... ]
# Settings related to the remote read feature.
remote_read:
[ - <remote_read> ... ]
這裡有一個有效的示例配置檔案
3.3. 查詢
Prometheus提供了一種名為PromQL(Prometheus查詢語言)的函數式查詢語言,允許使用者實時選擇和聚合時間序列資料。表達式的結果既可以顯示為圖形,也可以在Prometheus的表達式浏覽器中作為表格資料檢視,或者通過HTTP API由外部系統使用。
3.3.1. 表達式資料類型
在Prometheus的表達式語言中,表達式或子表達式可以計算為以下四種類型之一:
- Instant vector(瞬時向量):一組時間序列,每個時間序列包含一個樣本,所有樣本共享相同的時間戳
- Range vector(範圍向量):一組時間序列,其中包含每個時間序列随時間變化的資料點範圍
- Scalar(标量):一個簡單的數值浮點值
- String(字元串):一個簡單的字元串值,目前未使用
3.3.2. 字面值
字元串字面值
字元串可以指定為單引号、雙引号或反引号中的文字。例如:
1 "this is a string"
2 'these are unescaped: \n \\ \t'
3 `these are not unescaped: \n ' " \t`
浮點數字面值
例如:-2.34
3.3.3. 時間序列選擇器
瞬時向量選擇器
瞬時向量選擇器允許在給定的時間戳(瞬時)上為每個時間序列選擇一組時間序列和一個樣本值:在最簡單的形式中,隻指定一個度量名稱。這樣一個向量就會包含這個度量名稱的所有時間序列元素。
下面的例子,選擇名額名稱是http_requests_total的所有時間序列:
http_requests_total
通過在花括号({ })中添加一組比對的标簽,可以進一步過濾這些時間序列。
下面的例子,選擇名額名稱是http_requests_total,并且有job标簽值是prometheus,并且group标簽值是canary的時間序列:
http_requests_total{job="prometheus",group="canary"}
标簽比對操作符:
- = : 選擇與提供的字元串完全相同的标簽(等于)
- != :選擇不等于提供的字元串的标簽(不等于)
- =~ :正則比對
- !~ : 非正則比對
下面的例子,選擇所有staging, testing, development環境,并且HTTP請求方式不是GET的http_requests_total時間序列
http_requests_total{environment=~"staging|testing|development",method!="GET"}
不要比對空标簽
{job=~".+"} # Good!
{job=~".*",method="get"} # Good!
3.3.4. 範圍向量選擇器
範圍向量字面量的工作原理與瞬時向量字面量類似,隻是它們從目前瞬時量中選擇一個樣本範圍。從文法上講,範圍持續時間被添加到向量選擇器末尾的方括号([ ])中,以指定應該為每個結果範圍向量元素擷取多少時間值。
時間期限指定為一個數字,緊接其後的是下列機關之一:s(秒)、m(分鐘)、h(小時)、d(天) 、w(周)、y(年)
下面的例子,選擇名額名是http_requests_total,且job标簽值是prometheus的已經記錄的最近5分鐘内的時間序列:
http_requests_total{job="prometheus"}[5m]
Offset修飾符
下面的表達式傳回http_requests_total在過去5分鐘相對于目前查詢計算時間的值:
http_requests_total offset 5m
注意,offset總是緊跟在選擇器後面的
sum(http_requests_total{method="GET"} offset 5m)
下面的例子,傳回一周前的最近5分鐘http_requests_total的時間序列
rate(http_requests_total[5m] offset 1w)
3.3.5. 子查詢
Syntax: <instant_query> '[' <range> ':' [<resolution>] ']' [ offset <duration> ]
3.3.5. 運算符
Prometheus的查詢語言支援基本的邏輯運算符和算術運算符。
算術二進制運算符
+(加)、-(減)、*(乘)、/(除)、%(餘數)、^(指數)
二進制算術運算符定義在标量/标量、向量/标量和向量/向量值對之間
比較二進制運算符
== 、!= 、> 、< 、>= 、<=
邏輯運算符
and 、or 、unless
聚合運算符
sum(求和)、min(最小值)、max(最大值)、avg(求平均)、stddev(标準偏差)、stdvar(方差)、count(個數)、count_values(相同值的元素個數)、bottomk(樣本值的最小元素)、topk(樣本值的最大元素)、quantile(0 ≤ φ ≤ 1)
這些操作符既可以用于聚合所有标簽次元,也可以通過包含without子句或by子句來儲存不同的次元。
1 <aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]
例如,假設http_requests_total有application 、 instance 、 group三個标簽,那麼下面兩個是等價的:
1 sum(http_requests_total) without (instance)
2 sum(http_requests_total) by (application, group)
3.3.6. 函數
https://prometheus.io/docs/prometheus/latest/querying/functions/
3.3.7. 示例
1 # 傳回http_requests_total的所有時間序列
2 http_requests_total
3
4 # 傳回http_requests_total的且限定了job和handler标簽的時間序列
5 http_requests_total{job="apiserver", handler="/api/comments"}
6 http_requests_total{job="apiserver", handler="/api/comments"}[5m]
7
8 # 正規表達式
9 http_requests_total{job=~".*server"}
10 http_requests_total{status!~"4.."}
11
12 # 過去的5分鐘内每秒HTTP請求速率
13 rate(http_requests_total{job="api-server"}[5m])
14 # 過去的30分鐘内每5分鐘
15 rate(http_requests_total[5m])[30m:1m]
16 # 過去5分鐘的所有請求速率求和,保留job次元
17 sum(rate(http_requests_total[5m])) by (job)
18 # cpu使用率最高的前3個
19 topk(3, sum(rate(instance_cpu_time_ns[5m])) by (app, proc))
4. Grafana支援
Grafana支援查詢Prometheus
下面是Grafana dashboard查詢Prometheus資料的例子:
使用
預設情況下,Grafana監聽http://localhost:3000,預設用admin/admin登入
建立一個Prometheus資料源,接着建立面闆并定義查詢的名額
剛開始,如果不知道PromeQL怎麼寫,可以去Prometheus上去找 http://localhost:9090/graph
https://prometheus.io/docs/introduction/overview/
https://prometheus.io/docs/alerting/overview/