在第1章中為了采集主機(jī)的監(jiān)控樣本數(shù)據(jù),我們在主機(jī)上安裝了一個(gè)Node Exporter程序,該程序?qū)ν獗┞读艘粋€(gè)用于獲取當(dāng)前監(jiān)控樣本數(shù)據(jù)的HTTP訪問地址。這樣的一個(gè)程序稱為Exporter,Exporter的實(shí)例稱為一個(gè)Target。Prometheus通過輪詢的方式定時(shí)從這些Target中獲取監(jiān)控?cái)?shù)據(jù)樣本,并且存儲在數(shù)據(jù)庫當(dāng)中。前面的示例都是基于Node Exporter去講解的,以及一些http數(shù)據(jù)的云講解。這一章就詳細(xì)講述Exporter。
4.1 Exporter是什么
廣義上講所有可以向Prometheus提供監(jiān)控樣本數(shù)據(jù)的程序都可以被稱為一個(gè)Exporter。而Exporter的一個(gè)實(shí)例稱為target,如下所示,Prometheus通過輪詢的方式定期從這些target中獲取樣本數(shù)據(jù):
4.1.1 Exporter的來源
從Exporter的來源上來講,主要分為兩類:
- 社區(qū)提供的
Prometheus社區(qū)提供了豐富的Exporter實(shí)現(xiàn),涵蓋了從基礎(chǔ)設(shè)施,中間件以及網(wǎng)絡(luò)等各個(gè)方面的監(jiān)控功能。這些Exporter可以實(shí)現(xiàn)大部分通用的監(jiān)控需求。下表列舉一些社區(qū)中常用的Exporter:
范圍 | 常用Exporter |
---|---|
數(shù)據(jù)庫 | MySQL Exporter, Redis Exporter, MongoDB Exporter, MSSQL Exporter等 |
硬件 | Apcupsd Exporter,IoT Edison Exporter, IPMI Exporter, Node Exporter等 |
消息隊(duì)列 | Beanstalkd Exporter, Kafka Exporter, NSQ Exporter, RabbitMQ Exporter等 |
存儲 | Ceph Exporter, Gluster Exporter, HDFS Exporter, ScaleIO Exporter等 |
HTTP服務(wù) | Apache Exporter, HAProxy Exporter, Nginx Exporter等 |
API服務(wù) | AWS ECS Exporter, Docker Cloud Exporter, Docker Hub Exporter, GitHub Exporter等 |
日志 | Fluentd Exporter, Grok Exporter等 |
監(jiān)控系統(tǒng) | Collectd Exporter, Graphite Exporter, InfluxDB Exporter, Nagios Exporter, SNMP Exporter等 |
其它 | Blockbox Exporter, JIRA Exporter, Jenkins Exporter, Confluence Exporter等 |
- 用戶自定義的
除了直接使用社區(qū)提供的Exporter程序以外,用戶還可以基于Prometheus提供的Client Library創(chuàng)建自己的Exporter程序,目前Promthues社區(qū)官方提供了對以下編程語言的支持:Go、Java/Scala、Python、Ruby。同時(shí)還有第三方實(shí)現(xiàn)的如:Bash、C++、Common Lisp、Erlang,、Haskeel、Lua、Node.js、PHP、Rust等。
4.1.2 Exporter的運(yùn)行方式
從Exporter的運(yùn)行方式上來講,又可以分為:
- 獨(dú)立使用的
以我們已經(jīng)使用過的Node Exporter為例,由于操作系統(tǒng)本身并不直接支持Prometheus,同時(shí)用戶也無法通過直接從操作系統(tǒng)層面上提供對Prometheus的支持。因此,用戶只能通過獨(dú)立運(yùn)行一個(gè)程序的方式,通過操作系統(tǒng)提供的相關(guān)接口,將系統(tǒng)的運(yùn)行狀態(tài)數(shù)據(jù)轉(zhuǎn)換為可供Prometheus讀取的監(jiān)控?cái)?shù)據(jù)。 除了Node Exporter以外,比如MySQL Exporter、Redis Exporter等都是通過這種方式實(shí)現(xiàn)的。 這些Exporter程序扮演了一個(gè)中間代理人的角色。
- 集成到應(yīng)用中的
為了能夠更好的監(jiān)控系統(tǒng)的內(nèi)部運(yùn)行狀態(tài),有些開源項(xiàng)目如Kubernetes,ETCD等直接在代碼中使用了Prometheus的Client Library,提供了對Prometheus的直接支持。這種方式打破的監(jiān)控的界限,讓應(yīng)用程序可以直接將內(nèi)部的運(yùn)行狀態(tài)暴露給Prometheus,適合于一些需要更多自定義監(jiān)控指標(biāo)需求的項(xiàng)目。
4.1.3 Exporter規(guī)范
所有的Exporter程序都需要按照Prometheus的規(guī)范,返回監(jiān)控的樣本數(shù)據(jù)。以Node Exporter為例,當(dāng)訪問/metrics地址時(shí)會返回以下內(nèi)容:
# HELP node_cpu_guest_seconds_total Seconds the cpus spent in guests (VMs) for each mode.
# TYPE node_cpu_guest_seconds_total counter
node_cpu_guest_seconds_total{cpu="0",mode="nice"} 0
這是一種基于文本的格式規(guī)范,在Prometheus 2.0之前的版本還支持Protocol buffer規(guī)范。相比于Protocol buffer文本具有更好的可讀性,以及跨平臺性。Prometheus 2.0的版本也已經(jīng)不再支持Protocol buffer,這里就不對Protocol buffer規(guī)范做詳細(xì)的闡述。
Exporter返回的樣本數(shù)據(jù),主要由三個(gè)部分組成:樣本的一般注釋信息(HELP),樣本的類型注釋信息(TYPE)和樣本。Prometheus會對Exporter響應(yīng)的內(nèi)容逐行解析:
如果當(dāng)前行以# HELP開始,Prometheus將會按照以下規(guī)則對內(nèi)容進(jìn)行解析,得到當(dāng)前的指標(biāo)名稱以及相應(yīng)的說明信息:
# HELP <metrics_name> <doc_string>
如果當(dāng)前行以# TYPE開始,Prometheus會按照以下規(guī)則對內(nèi)容進(jìn)行解析,得到當(dāng)前的指標(biāo)名稱以及指標(biāo)類型:
# TYPE <metrics_name> <metrics_type>
TYPE注釋行必須出現(xiàn)在指標(biāo)的第一個(gè)樣本之前。如果沒有明確的指標(biāo)類型需要返回為untyped。 除了# 開頭的所有行都會被視為是監(jiān)控樣本數(shù)據(jù)。 每一行樣本需要滿足以下格式規(guī)范:
metric_name [
"{" label_name "=" `"` label_value `"` { "," label_name "=" `"` label_value `"` } [ "," ] "}"
] value [ timestamp ]
其中metric_name和label_name必須遵循PromQL的格式規(guī)范要求。value是一個(gè)float格式的數(shù)據(jù),timestamp的類型為int64(從1970-01-01 00:00:00以來的毫秒數(shù)),timestamp為可選默認(rèn)為當(dāng)前時(shí)間。具有相同metric_name的樣本必須按照一個(gè)組的形式排列,并且每一行必須是唯一的指標(biāo)名稱和標(biāo)簽鍵值對組合。
需要特別注意的是對于histogram和summary類型的樣本。需要按照以下約定返回樣本數(shù)據(jù):
類型為summary或者h(yuǎn)istogram的指標(biāo)x,該指標(biāo)所有樣本的值的總和需要使用一個(gè)單獨(dú)的x_sum指標(biāo)表示。
類型為summary或者h(yuǎn)istogram的指標(biāo)x,該指標(biāo)所有樣本的總數(shù)需要使用一個(gè)單獨(dú)的x_count指標(biāo)表示。
對于類型為summary的指標(biāo)x,其不同分位數(shù)quantile所代表的樣本,需要使用單獨(dú)的x{quantile="y"}表示。
對于類型histogram的指標(biāo)x為了表示其樣本的分布情況,每一個(gè)分布需要使用x_bucket{le="y"}表示,其中y為當(dāng)前分布的上位數(shù)。同時(shí)必須包含一個(gè)樣本x_bucket{le="+Inf"},并且其樣本值必須和x_count相同。
對于histogram和summary的樣本,必須按照分位數(shù)quantile和分布le的值的遞增順序排序。
以下是類型為histogram和summary的樣本輸出示例:
# A histogram, which has a pretty complex representation in the text format:
# HELP http_request_duration_seconds A histogram of the request duration.
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{le="0.05"} 24054
http_request_duration_seconds_bucket{le="0.1"} 33444
http_request_duration_seconds_bucket{le="0.2"} 100392
http_request_duration_seconds_bucket{le="+Inf"} 144320
http_request_duration_seconds_sum 53423
http_request_duration_seconds_count 144320
# Finally a summary, which has a complex representation, too:
# HELP rpc_duration_seconds A summary of the RPC duration in seconds.
# TYPE rpc_duration_seconds summary
rpc_duration_seconds{quantile="0.01"} 3102
rpc_duration_seconds{quantile="0.05"} 3272
rpc_duration_seconds{quantile="0.5"} 4773
rpc_duration_seconds_sum 1.7560473e+07
rpc_duration_seconds_count 2693
對于某些Prometheus還沒有提供支持的編程語言,用戶只需要按照以上規(guī)范返回響應(yīng)的文本數(shù)據(jù)即可。
4.1.4 指定樣本格式的版本
在Exporter響應(yīng)的HTTP頭信息中,可以通過Content-Type指定特定的規(guī)范版本,例如:
HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Length: 2906
Content-Type: text/plain; version=0.0.4
Date: Sat, 17 Mar 2018 08:47:06 GMT
其中version用于指定Text-based的格式版本,當(dāng)沒有指定版本的時(shí)候,默認(rèn)使用最新格式規(guī)范的版本。同時(shí)HTTP響應(yīng)頭還需要指定壓縮格式為gzip。
4.2 常用Exporter
4.2.1 容器監(jiān)控:CAdvisor
使用CAdvisor
CAdvisor是Google開源的一款用于展示和分析容器運(yùn)行狀態(tài)的可視化工具。通過在主機(jī)上運(yùn)行CAdvisor用戶可以輕松的獲取到當(dāng)前主機(jī)上容器的運(yùn)行統(tǒng)計(jì)信息,并以圖表的形式向用戶展示。
啟動(dòng)CAdvisor非常簡單,直接在要監(jiān)控的Docker服務(wù)器上運(yùn)行該容器即可:
docker run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:rw \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--publish=8080:8080 \
--detach=true \
--name=cadvisor \
google/cadvisor:latest
我的Docker主機(jī)的IP為:192.168.113.70,打開8080端口即可看到當(dāng)前主機(jī)的運(yùn)行狀態(tài)。
Advisor是一個(gè)簡單易用的工具,相比于使用Docker命令行工具,用戶不用再登錄到服務(wù)器中即可以可視化圖表的形式查看主機(jī)上所有容器的運(yùn)行狀態(tài)。
而在多主機(jī)的情況下,在所有節(jié)點(diǎn)上運(yùn)行一個(gè)CAdvisor再通過各自的UI查看監(jiān)控信息顯然不太方便,同時(shí)CAdvisor默認(rèn)只保存2分鐘的監(jiān)控?cái)?shù)據(jù)。好消息是CAdvisor已經(jīng)內(nèi)置了對Prometheus的支持。訪問http://192.168.113.70:8080/metrics即可獲取到標(biāo)準(zhǔn)的Prometheus監(jiān)控樣本輸出:
# HELP container_fs_limit_bytes Number of bytes that can be consumed by the container on this filesystem.
# TYPE container_fs_limit_bytes gauge
container_fs_limit_bytes{container_label_maintainer="",device="/dev/mapper/centos-root",id="/",image="",name=""} 2.146435072e+10
container_fs_limit_bytes{container_label_maintainer="",device="/dev/mapper/centos-root",id="/docker/0fb99e75206028cfb783e29af806393ee38df289fbbe0c324038832500db94e4",image="redis",name="redis-server"} 2.146435072e+10
container_fs_limit_bytes{container_label_maintainer="",device="/dev/mapper/centos-root",id="/docker/a91d3c038964bc6fd3da6c0023fd49c56d3dbf9e814f670d38331071e5e7cb20",image="google/cadvisor:latest",name="cadvisor"} 2.146435072e+10
下面表格中列舉了一些CAdvisor中獲取到的典型監(jiān)控指標(biāo):
指標(biāo)名稱 | 類型 | 含義 |
---|---|---|
container_cpu_load_average_10s | gauge | 過去10秒容器CPU的平均負(fù)載 |
container_cpu_usage_seconds_total | counter | 容器在每個(gè)CPU內(nèi)核上的累積占用時(shí)間 (單位:秒) |
container_cpu_system_seconds_total | counter | System CPU累積占用時(shí)間(單位:秒) |
container_cpu_user_seconds_total | counter | User CPU累積占用時(shí)間(單位:秒) |
container_fs_usage_bytes | gauge | 容器中文件系統(tǒng)的使用量(單位:字節(jié)) |
container_fs_limit_bytes | gauge | 容器可以使用的文件系統(tǒng)總量(單位:字節(jié)) |
container_fs_reads_bytes_total | counter | 容器累積讀取數(shù)據(jù)的總量(單位:字節(jié)) |
container_fs_writes_bytes_total | counter | 容器累積寫入數(shù)據(jù)的總量(單位:字節(jié)) |
container_memory_max_usage_bytes | gauge | 容器的最大內(nèi)存使用量(單位:字節(jié)) |
container_memory_usage_bytes | gauge | 容器當(dāng)前的內(nèi)存使用量(單位:字節(jié) |
container_spec_memory_limit_bytes | gauge | 容器的內(nèi)存使用量限制 |
machine_memory_bytes | gauge | 當(dāng)前主機(jī)的內(nèi)存總量 |
container_network_receive_bytes_total | counter | 容器網(wǎng)絡(luò)累積接收數(shù)據(jù)總量(單位:字節(jié)) |
container_network_transmit_bytes_total | counter | 容器網(wǎng)絡(luò)累積傳輸數(shù)據(jù)總量(單位:字節(jié)) |
與Prometheus集成
修改prometheus.yml 文件,將cAdvisor添加監(jiān)控?cái)?shù)據(jù)采集任務(wù)目標(biāo)當(dāng)中:
- job_name: cadvisor
static_configs:
- targets:
- localhost:8080
重啟Prometheus服務(wù),在Prometheus UI中查看到當(dāng)前所有的Target狀態(tài):
當(dāng)能夠正常采集到cAdvisor的樣本數(shù)據(jù)后,可以通過以下表達(dá)式計(jì)算容器的CPU使用率:
sum(irate(container_cpu_usage_seconds_total{image!=""}[1m])) without (cpu)
查詢?nèi)萜鲀?nèi)存使用量(單位:字節(jié)):
container_memory_usage_bytes{image!=""}
查詢?nèi)萜骶W(wǎng)絡(luò)接收量速率(單位:字節(jié)/秒):
sum(rate(container_network_receive_bytes_total{image!=""}[1m])) without (interface)
查詢?nèi)萜骶W(wǎng)絡(luò)傳輸量速率(單位:字節(jié)/秒):
sum(rate(container_network_transmit_bytes_total{image!=""}[1m])) without (interface)
當(dāng)然,在Prometheus查詢也不是辦法,我們看下在Grafana下是怎樣的一個(gè)表現(xiàn)吧。
這樣是不是直觀又帥氣呢。
4.2.2 監(jiān)控MySQL運(yùn)行狀態(tài):MySQLD Exporter
mysqld_exporter是官方出品的mysql性能及資源利用率監(jiān)控的exporter。可以在Prometheus的官網(wǎng)下載,最新版本0.12.1。這里就演示怎么下載安裝,二進(jìn)制包很簡單的。
在我的測試環(huán)境下,剛好有個(gè)MariaDB,版本是10.4.6。考慮到MariaDB和MySQL師出同源,這里就用MariaDB來做演示了。
創(chuàng)建數(shù)據(jù)庫用戶
獲取mysql的性能狀態(tài),首先要能登錄mysql才行的,所以這里我們先創(chuàng)建一個(gè)用來獲取mysql性能信息的本地賬戶。
CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'yourpasswd';
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
啟動(dòng)mysqld exporter
按照之前我們新建目錄的規(guī)范,新建一個(gè)目錄用來存放各種exporter,然后解壓下載好的mysqld exporter。
mkdir /usr/local/prometheus_exporter
tar -xf mysqld_exporter-0.11.0.linux-amd64.tar.gz
mv mysqld_exporter-0.11.0.linux-amd64 /usr/local/prometheus_exporter/
cd /usr/local/prometheus_exporter/
ln -s mysqld_exporter-0.11.0.linux-amd64 mysqld_exporter
接下來我們在該服務(wù)器上啟動(dòng)mysqld exporter,啟動(dòng)之前我們先要新建一個(gè)配置文件,里面配置了mysql的連接信息及剛剛創(chuàng)建的賬號密碼:
vim /usr/local/prometheus_exporter/mysqld_exporter/my.cnf
[client]
user=exporter
password="yourpasswd"
socket=/tmp/mysql.sock
保存退出后記得修改這個(gè)文件的權(quán)限,密碼屬于敏感信息:
chmod 600 /usr/local/prometheus_exporter/mysqld_exporter/my.cnf
然后啟動(dòng)mysqld exporter
cd /usr/local/prometheus_exporter/mysqld_exporter
nohup ./mysqld_exporter --config.my-cnf=my.cnf &
集成Prometheus
mysqld exporter默認(rèn)會啟動(dòng)9104端口,我們在Prometheus的配置文件中添加對應(yīng)的配置:
#采集mysqld運(yùn)行數(shù)據(jù)
- job_name: mysqld
static_configs:
- targets:
- 192.168.1.174:9104
重啟Prometheus,在target菜單下能看到新增的監(jiān)控任務(wù)
Grafana展示
為了更好展現(xiàn)監(jiān)控的結(jié)果,我們使用Grafana對數(shù)據(jù)進(jìn)行展示,導(dǎo)入模板 7362,可以看到如下的界面:
這里可以很直觀地看到很多游人的信息,比如QPS、連接數(shù)等等
4.2.3 網(wǎng)絡(luò)探測:Blackbox Exporter
前面介紹的兩種export都是屬于白盒監(jiān)控的,就是說你能看到監(jiān)控目標(biāo)里面幾乎你想要的指標(biāo),讓你對監(jiān)控目標(biāo)有個(gè)全面的了解。對比于白盒監(jiān)控,黑盒監(jiān)控看到的就是最表面的狀態(tài),比如說:網(wǎng)頁打不開、服務(wù)連接不上。但是就是這種的狀態(tài),恰恰是我們非常需要的,這是非常貼合實(shí)際用戶的。所以黑盒監(jiān)控可以說是對白盒監(jiān)控的一種補(bǔ)充。
在Prometheus中使用黑盒監(jiān)控需要安裝部署blackbox exporter,和其他的exporter,這是golang寫的二進(jìn)制包,可以直接使用。blackbox exporter內(nèi)置了http、tcp、dns和icmp等探針類型,在啟動(dòng)blackbox exporter后,在Prometheus的配置文件中可以定義對目標(biāo)的檢測。大概流程如下:
- 啟動(dòng)blackbox exporter
nohup ./blackbox_exporter --config.file=blackbox.yml &
- 在Prometheus中添加探測的目標(biāo),這里用http探針去檢測百度網(wǎng)站
- job_name: baidu_http2xx_probe
params:
module:
- http_2xx
target:
- baidu.com
metrics_path: /probe
static_configs:
- targets:
- 127.0.0.1:9115
重啟Prometheus后可以在target菜單看到這個(gè)監(jiān)控任務(wù),可以點(diǎn)擊連接看看返回的內(nèi)容都有些什么。
點(diǎn)擊鏈接打開 http://192.168.113.52:9115/probe?module=http_2xx&target=baidu.com
,查看返回的結(jié)果:
更加具體的介紹請自行百度,書本也沒有太過詳細(xì)。
4.3 使用Java自定義Exporter
直到現(xiàn)在為止,java仍然是企業(yè)應(yīng)用中的首先開發(fā)語言。想要讓自己開發(fā)的java產(chǎn)品能夠使用Prometheus進(jìn)行監(jiān)控貌似也不大難,因?yàn)镻rometheus有提供對應(yīng)的方法給我們。因?yàn)槲也皇情_發(fā)人員,這里就略過了這部分的內(nèi)容。里面提到的方法有兩個(gè):使用Client Java構(gòu)建Exporter程序、在應(yīng)用中內(nèi)置Prometheus支持。
可以看具體的這個(gè)連接: https://yunlzheng.gitbook.io/prometheus-book/part-ii-prometheus-jin-jie/exporter/custom_exporter_with_java