#Prometheus 是一款基於時序資料庫的開源監控告警系統,說起Prometheus 則不得不提SoundCloud,這是一個線上音樂分享的平台,類似於做影片分享的YouTube,由於他們在微服務架構的道路上越走越遠,出現了成百上千的服務,使用傳統的監控系統StatsD和Graphite 有大量的限制。
於是他們在 2012 年開始著手開發一套全新的監控系統。 Prometheus 的原作者是Matt T. Proud,他也是在2012 年加入SoundCloud 的,實際上,在加入SoundCloud 之前,Matt 一直就職於Google,他從Google 的集群管理器Borg 和它的監控系統Borgmon 中獲取靈感,開發了開源的監控系統Prometheus,和Google 的許多專案一樣,使用的程式語言是Go。
很顯然,Prometheus 作為一個微服務架構監控系統的解決方案,它和容器也脫不開關係。早在 2006 年 8 月 9 日,Eric Schmidt 在搜尋引擎大會上首次提出了雲端運算(Cloud Computing)的概念,在之後的十多年裡,雲端運算的發展勢如破竹。
在2013 年,Pivotal 的Matt Stine 又提出了雲端原生(Cloud Native)的概念,雲端原生由微服務架構、DevOps 和以容器為代表的敏捷基礎架構組成,幫助企業快速、持續、可靠、規模化地交付軟體。
為了統一雲端運算介面和相關標準,2015 年 7 月,隸屬於 Linux 基金會的 雲端原生運算基金會(CNCF,Cloud Native Computing Foundation) 應運而生。第一個加入 CNCF 的專案是 Google 的 Kubernetes,而 Prometheus 是第二個加入的(2016 年)。
我們在SoundCloud 的官方部落格中可以找到一篇關於他們為什麼需要新開發一個監控系統的文章Prometheus: Monitoring at SoundCloud,在這篇文章中,他們介紹到,他們需要的監控系統必須滿足下面四個特性:
實際上,多維度資料模型和強大的查詢語言這兩個特性,正是時序資料庫所要求的,所以Prometheus 不只是一個監控系統,同時也是一個時序資料庫。那為什麼 Prometheus 不直接使用現有的時序資料庫作為後端儲存呢?這是因為 SoundCloud 不僅希望他們的監控系統有著時序資料庫的特點,而且還需要部署和維護非常方便。
縱觀比較流行的時序資料庫(請參閱下面的附錄),他們要麼組件太多,要麼外部依賴繁重,例如:Druid 有Historical、MiddleManager、Broker、Coordinator、Overlord、Router 一堆的組件,而且也依賴ZooKeeper、Deep storage(HDFS 或S3 等),Metadata store(PostgreSQL 或MySQL),部署和維護起來成本非常高。而 Prometheus 採用去中心化架構,可以獨立部署,不依賴外部的分散式存儲,你可以在幾分鐘的時間內就可以搭建出一套監控系統。
此外,Prometheus 資料收集方式也非常靈活。要收集目標的監控數據,首先需要在目標處安裝數據採集組件,這被稱之為Exporter,它會在目標處收集監控數據,並暴露出一個HTTP 接口供Prometheus 查詢,Prometheus 透過Pull 的方式來採集數據,這和傳統的Push 模式不同。
不過 Prometheus 也提供了一種方式來支援 Push 模式,你可以將你的資料推送到 Push Gateway,Prometheus 透過 Pull 的方式從 Push Gateway 取得資料。目前的 Exporter 已經可以採集絕大多數的第三方數據,例如 Docker、HAProxy、StatsD、JMX 等等,官網有一份 Exporter 的列表。
除了這四大特性,隨著Prometheus 的不斷發展,開始支援越來越多的高級特性,例如:服務發現,更豐富的圖表展示,使用外部存儲,強大的告警規則和多樣的通知方式。
下圖是Prometheus 的整體架構圖:
#Prometheus 可以支援多種安裝方式,包括Docker、Ansible、Chef、Puppet、Saltstack等。以下介紹最簡單的兩種方式,一種是直接使用編譯好的可執行文件,開箱即用,另一種是使用 Docker 映像。
首先從官網的下載頁面獲取Prometheus 的最新版本和下載地址,目前最新版本是2.4.3(2018年10月),執行下面的命令下載並解壓:
$ wget https://github.com/prometheus/prometheus/releases/download/v2.4.3/prometheus-2.4.3.linux-amd64.tar.gz $ tar xvfz prometheus-2.4.3.linux-amd64.tar.gz
然後切換到解壓縮目錄,檢查Prometheus 版本:
$ cd prometheus-2.4.3.linux-amd64 $ ./prometheus --version prometheus, version 2.4.3 (branch: HEAD, revision: 167a4b4e73a8eca8df648d2d2043e21bdb9a7449) build user: root@1e42b46043e9 build date: 20181004-08:42:02 go version: go1.11.1
運行Prometheus server:
$ ./prometheus --config.file=prometheus.yml
使用Docker 安裝Prometheus更簡單,執行下面的指令即可:
$ sudo docker run -d -p 9090:9090 prom/prometheus
一般情況下,我們也會指定設定檔的位置:
$ sudo docker run -d -p 9090:9090 \ -v ~/docker/prometheus/:/etc/prometheus/ \ prom/prometheus
我們把設定檔放在本機 ~/docker /prometheus/prometheus.yml
,這樣可以方便編輯和查看,透過 -v
參數將本地的設定檔掛載到 /etc/prometheus/
位置,這是prometheus 在容器中預設載入的設定檔位置。
如果我们不确定默认的配置文件在哪,可以先执行上面的不带 -v
参数的命令,然后通过 docker inspect
命名看看容器在运行时默认的参数有哪些(下面的 Args 参数):
$ sudo docker inspect 0c [...] "Id": "0c4c2d0eed938395bcecf1e8bb4b6b87091fc4e6385ce5b404b6bb7419010f46", "Created": "2018-10-15T22:27:34.56050369Z", "Path": "/bin/prometheus", "Args": [ "--config.file=/etc/prometheus/prometheus.yml", "--storage.tsdb.path=/prometheus", "--web.console.libraries=/usr/share/prometheus/console_libraries", "--web.console.templates=/usr/share/prometheus/consoles" ], [...]
正如上面两节看到的,Prometheus 有一个配置文件,通过参数 <span style="outline: 0px;color: rgb(0, 0, 0);">--config.file</span>
来指定,配置文件格式为 YAML。我们可以打开默认的配置文件 <span style="outline: 0px;color: rgb(0, 0, 0);">prometheus.yml</span>
看下里面的内容:
/etc/prometheus $ cat prometheus.yml # my global config global: scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. # scrape_timeout is set to the global default (10s). # Alertmanager configuration alerting: alertmanagers: - static_configs: - targets: # - alertmanager:9093 # Load rules once and periodically evaluate them according to the global 'evaluation_interval'. rule_files: # - "first_rules.yml" # - "second_rules.yml" # A scrape configuration containing exactly one endpoint to scrape: # Here it's Prometheus itself. scrape_configs: # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config. - job_name: 'prometheus' # metrics_path defaults to '/metrics' # scheme defaults to 'http'. static_configs: - targets: ['localhost:9090']
Prometheus 默认的配置文件分为四大块:
##global 區塊:Prometheus 的全域配置,例如
global 區塊:Prometheus 的全域配置,例如
rule_files 區塊:警告規則,這個我們後面再看;
##三、學習PromQL
第一次造訪這個頁面可能會不知所措,我們可以先看看其他選單下的內容,例如:Alerts 展示了定義的所有告警規則,Status 可以查看各種Prometheus 的狀態訊息,有Runtime & Build Information、Command-Line Flags、Configuration、Rules、Targets、Service Discovery 等等。
實際上 Graph 頁面才是 Prometheus 最強大的功能,在這裡我們可以使用 Prometheus 提供的一種特殊表達式來查詢監控數據,這個表達式被稱為 PromQL(Prometheus Query Language)。透過 PromQL 不僅可以在 Graph 頁面查詢數據,而且還可以透過 Prometheus 提供的 HTTP API 來查詢。查詢的監控資料有清單和曲線圖兩種展現形式(對應上圖 Console 和 Graph 這兩個標籤)。
我們上面說過,Prometheus 本身也揭露了許多的監控指標,也可以在Graph 頁面查詢,展開Execute 按鈕旁的下拉框,可以看到很多指標名稱,我們隨便選一個,譬如: promhttp_metric_handler_requests_total
,這個指標表示 /metrics
頁面的造訪次數,Prometheus 就是透過這個頁面來抓取自身的監控資料的。在Console 標籤中查詢結果如下:
#上面在介紹Prometheus 的設定檔時,可以看到 scrape_interval
參數是15s,也就是說Prometheus 每15s 訪問一次 /metrics
頁面,所以我們過15s 刷新下頁面,可以看到指標值會自增。在 Graph 標籤中可以看得更明顯:
要学习 PromQL,首先我们需要了解下 Prometheus 的数据模型,一条 Prometheus 数据由一个指标名称(metric)和 N 个标签(label,N >= 0)组成的,比如下面这个例子:
promhttp_metric_handler_requests_total{code="200",instance="192.168.0.107:9090",job="prometheus"} 106
这条数据的指标名称为 promhttp_metric_handler_requests_total
,并且包含三个标签 code
、instance
和 job
,这条记录的值为 106。上面说过,Prometheus 是一个时序数据库,相同指标相同标签的数据构成一条时间序列。如果以传统数据库的概念来理解时序数据库,可以把指标名当作表名,标签是字段,timestamp 是主键,还有一个 float64 类型的字段表示值(Prometheus 里面所有值都是按 float64 存储)。
這種資料模型和 OpenTSDB 的資料模型是比較類似的,詳細的資訊可以參考官網文件 Data model。另外,關於指標和標籤的命名,官網有一些指導性的建議,可以參考 Metric and label naming 。
雖然Prometheus 裡儲存的資料都是float64 的數值,但如果我們按類型來分,可以把Prometheus 的資料分成四大類:
这四种类型的数据只在指标的提供方作区分,也就是上面说的 Exporter,如果你需要编写自己的 Exporter 或者在现有系统中暴露供 Prometheus 抓取的指标,你可以使用 Prometheus client libraries,这个时候你就需要考虑不同指标的数据类型了。如果你不用自己实现,而是直接使用一些现成的 Exporter,然后在 Prometheus 里查查相关的指标数据,那么可以不用太关注这块,不过理解 Prometheus 的数据类型,对写出正确合理的 PromQL 也是有帮助的。
我们从一些例子开始学习 PromQL,最简单的 PromQL 就是直接输入指标名称,比如:
# 表示 Prometheus 能否抓取 target 的指标,用于 target 的健康检查 up
这条语句会查出 Prometheus 抓取的所有 target 当前运行情况,譬如下面这样:
up{instance="192.168.0.107:9090",job="prometheus"} 1 up{instance="192.168.0.108:9090",job="prometheus"} 1 up{instance="192.168.0.107:9100",job="server"} 1 up{instance="192.168.0.108:9104",job="mysql"} 0
也可以指定某个 label 来查询:
up{job="prometheus"}
这种写法被称为 Instant vector selectors,这里不仅可以使用 =
号,还可以使用 !=
、=~
、!~
,比如下面这样:
up{job!="prometheus"} up{job=~"server|mysql"} up{job=~"192\.168\.0\.107.+"}
=~
是根据正则表达式来匹配,必须符合 RE2 的语法。
和 Instant vector selectors 相应的,还有一种选择器,叫做 Range vector selectors,它可以查出一段时间内的所有数据:
http_requests_total[5m]
这条语句查出 5 分钟内所有抓取的 HTTP 请求数,注意它返回的数据类型是 Range vector
,没办法在 Graph 上显示成曲线图,一般情况下,会用在 Counter 类型的指标上,并和 rate()
或 irate()
函数一起使用(注意 rate 和 irate 的区别)。
搜索公众号Java后端栈回复“面试”,送你一份惊喜礼包。
# 计算的是每秒的平均值,适用于变化很慢的 counter # per-second average rate of increase, for slow-moving counters rate(http_requests_total[5m]) # 计算的是每秒瞬时增加速率,适用于变化很快的 counter # per-second instant rate of increase, for volatile and fast-moving counters irate(http_requests_total[5m])
此外,PromQL 还支持 count
、sum
、min
、max
、topk
等 聚合操作,还支持 rate
、abs
、ceil
、floor
等一堆的 内置函数,更多的例子,还是上官网学习吧。如果感兴趣,我们还可以把 PromQL 和 SQL 做一个对比,会发现 PromQL 语法更简洁,查询性能也更高。
我们不仅仅可以在 Prometheus 的 Graph 页面查询 PromQL,Prometheus 还提供了一种 HTTP API 的方式,可以更灵活的将 PromQL 整合到其他系统中使用,譬如下面要介绍的 Grafana,就是通过 Prometheus 的 HTTP API 来查询指标数据的。实际上,我们在 Prometheus 的 Graph 页面查询也是使用了 HTTP API。
我们看下 Prometheus 的 HTTP API 官方文档,它提供了下面这些接口:
#雖然Prometheus 提供的Web UI 也可以很好的查看不同指標的視圖,但這個功能非常簡單,只適合用來除錯。要實現一個強大的監控系統,還需要一個能客製化展示不同指標的面板,能支援不同類型的展現方式(曲線圖、餅狀圖、熱點圖、TopN 等),這就是儀錶板(Dashboard)功能。
因此Prometheus 開發了一套儀錶板系統PromDash,不過很快這套系統就被廢棄了,官方開始推薦使用Grafana 來對Prometheus 的指標數據進行可視化,這不僅是因為Grafana 的功能非常強大,而且它和Prometheus 可以完美的無縫融合。
Grafana 是一個用於視覺化大型測量數據的開源系統,它的功能非常強大,介面也非常漂亮,使用它可以創建自訂的控制面板,你可以在面板中配置要顯示的數據和顯示方式,它支援許多不同的資料來源,例如:Graphite、InfluxDB、OpenTSDB、Elasticsearch、Prometheus 等,而且它也支援眾多的插件。
下面我們在體驗下使用 Grafana 來展示 Prometheus 的指標資料。首先我們來安裝 Grafana,我們使用最簡單的 Docker 安裝方式:
$ docker run -d -p 3000:3000 grafana/grafana
运行上面的 docker 命令,Grafana 就安装好了!你也可以采用其他的安装方式,参考 官方的安装文档。安装完成之后,我们访问 http://localhost:3000/
进入 Grafana 的登陆页面,输入默认的用户名和密码(admin/admin)即可。
要使用 Grafana,第一步当然是要配置数据源,告诉 Grafana 从哪里取数据,我们点击 Add data source 进入数据源的配置页面:
图片
我们在这里依次填上:
要注意的是,这里的 Access 指的是 Grafana 访问数据源的方式,有 Browser 和 Proxy 两种方式。Browser 方式表示当用户访问 Grafana 面板时,浏览器直接通过 URL 访问数据源的;而 Proxy 方式表示浏览器先访问 Grafana 的某个代理接口(接口地址是 /api/datasources/proxy/
),由 Grafana 的服务端来访问数据源的 URL,如果数据源是部署在内网,用户通过浏览器无法直接访问时,这种方式非常有用。
配置好資料來源,Grafana 會預設提供幾個已經配置好的面板供你使用,如下圖所示,預設提供了三個面板:Prometheus Stats、Prometheus 2.0 Stats 和 Grafana metrics。點擊 Import 就可以匯入並使用該面板。
目前為止,我們看到的都還只是一些沒有實際用途的指標,如果我們要在我們的生產環境中真正使用Prometheus,往往需要關注各種各樣的指標,譬如伺服器的CPU負載、記憶體佔用量、IO開銷、入網和出網流量等等。
正如上面所說,Prometheus 是使用Pull 的方式來獲取指標數據的,要讓Prometheus 從目標處獲得數據,首先必須在目標上安裝指標收集的程序,並暴露出HTTP 接口供Prometheus查詢,這個指標收集程序被稱為Exporter,不同的指標需要不同的Exporter 來收集,目前已經有大量的Exporter 可供使用,幾乎囊括了我們常用的各種系統和軟體。
官網列出了一份 常用 Exporter 的清單,各個 Exporter 都遵循一份端口約定,避免端口衝突,即從 9100 開始依次遞增,這裡是 完整的 Exporter 端口列表。另外值得注意的是,有些軟體和系統不需要安裝 Exporter,這是因為他們本身就提供了暴露 Prometheus 格式的指標資料的功能,例如 Kubernetes、Grafana、Etcd、Ceph 等。
这一节就让我们来收集一些有用的数据。
首先我们来收集服务器的指标,这需要安装 node_exporter,这个 exporter 用于收集 *NIX 内核的系统,如果你的服务器是 Windows,可以使用 WMI exporter。
和 Prometheus server 一样,node_exporter 也是开箱即用的:
$ wget https://github.com/prometheus/node_exporter/releases/download/v0.16.0/node_exporter-0.16.0.linux-amd64.tar.gz $ tar xvfz node_exporter-0.16.0.linux-amd64.tar.gz $ cd node_exporter-0.16.0.linux-amd64 $ ./node_exporter
node_exporter 启动之后,我们访问下 /metrics
接口看看是否能正常获取服务器指标:
$ curl http://localhost:9100/metrics
如果一切 OK,我们可以修改 Prometheus 的配置文件,将服务器加到 scrape_configs
中:
scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['192.168.0.107:9090'] - job_name: 'server' static_configs: - targets: ['192.168.0.107:9100']
修改配置后,需要重启 Prometheus 服务,或者发送 HUP
信号也可以让 Prometheus 重新加载配置:
$ killall -HUP prometheus
在 Prometheus Web UI 的 Status -> Targets 中,可以看到新加的服务器:
在 Graph 页面的指标下拉框可以看到很多名称以 node 开头的指标,譬如我们输入 node_load1
观察服务器负载:
如果想在 Grafana 中查看服务器的指标,可以在 Grafana 的 Dashboards 页面 搜索 node exporter
,有很多的面板模板可以直接使用,譬如:Node Exporter Server Metrics 或者 Node Exporter Full 等。我们打开 Grafana 的 Import dashboard 页面,输入面板的 URL(https://grafana.com/dashboards/405)或者 ID(405)即可。
一般情况下,node_exporter 都是直接运行在要收集指标的服务器上的,官方不推荐用 Docker 来运行 node_exporter。如果逼不得已一定要运行在 Docker 里,要特别注意,这是因为 Docker 的文件系统和网络都有自己的 namespace,收集的数据并不是宿主机真实的指标。可以使用一些变通的方法,比如运行 Docker 时加上下面这样的参数:
docker run -d \ --net="host" \ --pid="host" \ -v "/:/host:ro,rslave" \ quay.io/prometheus/node-exporter \ --path.rootfs /host
关于 node_exporter 的更多信息,可以参考 node_exporter 的文档 和 Prometheus 的官方指南 Monitoring Linux host metrics with the Node Exporter,另外,Julius Volz 的这篇文章 How To Install Prometheus using Docker on Ubuntu 14.04 也是很好的入门材料。
mysqld_exporter 是 Prometheus 官方提供的一个 exporter,我们首先 下载最新版本 并解压(开箱即用):
$ wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.11.0/mysqld_exporter-0.11.0.linux-amd64.tar.gz $ tar xvfz mysqld_exporter-0.11.0.linux-amd64.tar.gz $ cd mysqld_exporter-0.11.0.linux-amd64/
mysqld_exporter 需要连接到 mysqld 才能收集它的指标,可以通过两种方式来设置 mysqld 数据源。第一种是通过环境变量 DATA_SOURCE_NAME
,这被称为 DSN(数据源名称),它必须符合 DSN 的格式,一个典型的 DSN 格式像这样:user:password@(host:port)/
。
$ export DATA_SOURCE_NAME='root:123456@(192.168.0.107:3306)/' $ ./mysqld_exporter
另一种方式是通过配置文件,默认的配置文件是 ~/.my.cnf
,或者通过 --config.my-cnf
参数指定:
$ ./mysqld_exporter --config.my-cnf=".my.cnf"
配置文件的格式如下:
$ cat .my.cnf [client] host=localhost port=3306 user=root password=123456
如果要把 MySQL 的指标导入 Grafana,可以参考 这些 Dashboard JSON。另外,MySQL 系列面试题和答案全部整理好了,微信搜索互联网架构师,在后台发送:2T,可以在线阅读。
这里为简单起见,在 mysqld_exporter 中直接使用了 root 连接数据库,在真实环境中,可以为 mysqld_exporter 创建一个单独的用户,并赋予它受限的权限(PROCESS、REPLICATION CLIENT、SELECT),最好还限制它的最大连接数(MAX_USER_CONNECTIONS)。
CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'password' WITH MAX_USER_CONNECTIONS 3; GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
官方提供了两种收集 Nginx 指标的方式。另外,Nginx 系列面试题和答案全部整理好了,微信搜索互联网架构师,在后台发送:2T,可以在线阅读。
第一种是 Nginx metric library,这是一段 Lua 脚本(prometheus.lua),Nginx 需要开启 Lua 支持(libnginx-mod-http-lua 模块)。为方便起见,也可以使用 OpenResty 的 OPM(OpenResty Package Manager) 或者 luarocks(The Lua package manager) 来安装。
第二种是 Nginx VTS exporter,这种方式比第一种要强大的多,安装要更简单,支持的指标也更丰富,它依赖于 nginx-module-vts 模块,vts 模块可以提供大量的 Nginx 指标数据,可以通过 JSON、HTML 等形式查看这些指标。Nginx VTS exporter 就是通过抓取 /status/format/json
接口来将 vts 的数据格式转换为 Prometheus 的格式。
不過,在nginx-module-vts 最新的版本中增加了一個新介面:/status/format/prometheus
,這個介面可以直接回傳Prometheus 的格式,從這點這也能看出Prometheus 的影響力,估計Nginx VTS exporter 很快就要退役了(TODO:待驗證)。
除此之外,還有很多其他的方式來收集Nginx 的指標,例如:nginx_exporter
透過抓取Nginx 自帶的統計頁面 /nginx_status
可以取得一些比較簡單的指標(需要開啟 ngx_http_stub_status_module
模組);nginx_request_exporter
透過syslog 協定收集並分析Nginx 的access log 來統計HTTP 請求相關的一些指標;##nginx-x prometheus-shiny-exporter 和
nginx_request_exporter 類似,也是使用syslog 協定來收集access log,不過它是使用Crystal 語言寫的。還有
vovolie/lua-nginx-prometheus 基於 Openresty、Prometheus、Consul、Grafana 實現了針對網域名稱和 Endpoint 層級的流量統計。
最后让我们来看下如何收集 Java 应用的指标,Java 应用的指标一般是通过 JMX(Java Management Extensions) 来获取的,顾名思义,JMX 是管理 Java 的一种扩展,它可以方便的管理和监控正在运行的 Java 程序。
JMX Exporter 用于收集 JMX 指标,很多使用 Java 的系统,都可以使用它来收集指标,比如:Kafaka、Cassandra 等。首先我们下载 JMX Exporter:
$ wget https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.3.1/jmx_prometheus_javaagent-0.3.1.jar
JMX Exporter 是一个 Java Agent 程序,在运行 Java 程序时通过 -javaagent
参数来加载:
$ java -javaagent:jmx_prometheus_javaagent-0.3.1.jar=9404:config.yml -jar spring-boot-sample-1.0-SNAPSHOT.jar
其中,9404 是 JMX Exporter 暴露指标的端口,config.yml
是 JMX Exporter 的配置文件,它的内容可以 参考 JMX Exporter 的配置说明 。
然后检查下指标数据是否正确获取:
$ curl http://localhost:9404/metrics
至此,我们能收集大量的指标数据,也能通过强大而美观的面板展示出来。不过作为一个监控系统,最重要的功能,还是应该能及时发现系统问题,并及时通知给系统负责人,这就是 Alerting(告警)。
Prometheus 的告警功能被分成两部分:一个是告警规则的配置和检测,并将告警发送给 Alertmanager,另一个是 Alertmanager,它负责管理这些告警,去除重复数据,分组,并路由到对应的接收方式,发出报警。常见的接收方式有:Email、PagerDuty、HipChat、Slack、OpsGenie、WebHook 等。
我们在上面介绍 Prometheus 的配置文件时了解到,它的默认配置文件 prometheus.yml 有四大块:global
、alerting
、rule_files
、scrape_config
,其中 rule_files
块就是告警规则的配置项,alerting 块用于配置 Alertmanager,这个我们下一节再看。现在,先让我们在 rule_files
块中添加一个告警规则文件:
rule_files: - "alert.rules"
然后参考 官方文档,创建一个告警规则文件 alert.rules
:
groups: - name: example rules: # Alert for any instance that is unreachable for >5 minutes. - alert: InstanceDown expr: up == 0 for: 5m labels: severity: page annotations: summary: "Instance {{ $labels.instance }} down" description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes." # Alert for any instance that has a median request latency >1s. - alert: APIHighRequestLatency expr: api_http_request_latencies_second{quantile="0.5"} > 1 for: 10m annotations: summary: "High request latency on {{ $labels.instance }}" description: "{{ $labels.instance }} has a median request latency above 1s (current value: {{ $value }}s)"
这个规则文件里,包含了两条告警规则:InstanceDown
和 APIHighRequestLatency
。顾名思义,InstanceDown 表示当实例宕机时(up === 0)触发告警,APIHighRequestLatency 表示有一半的 API 请求延迟大于 1s 时(api_http_request_latencies_second{quantile="0.5"} > 1
)触发告警。
搜索公众号GitHub猿回复“理财”,送你一份惊喜礼包。
配置好后,需要重启下 Prometheus server,然后访问 http://localhost:9090/rules
可以看到刚刚配置的规则:
访问 http://localhost:9090/alerts
可以看到根据配置的规则生成的告警:
这里我们将一个实例停掉,可以看到有一条 alert 的状态是 PENDING
,这表示已经触发了告警规则,但还没有达到告警条件。这是因为这里配置的 for
参数是 5m,也就是 5 分钟后才会触发告警,我们等 5 分钟,可以看到这条 alert 的状态变成了 FIRING
。
虽然 Prometheus 的 <span style="outline: 0px;color: rgb(0, 0, 0);">/alerts</span>
页面可以看到所有的告警,但是还差最后一步:触发告警时自动发送通知。这是由 Alertmanager 来完成的,我们首先 下载并安装 Alertmanager,和其他 Prometheus 的组件一样,Alertmanager 也是开箱即用的:
$ wget https://github.com/prometheus/alertmanager/releases/download/v0.15.2/alertmanager-0.15.2.linux-amd64.tar.gz $ tar xvfz alertmanager-0.15.2.linux-amd64.tar.gz $ cd alertmanager-0.15.2.linux-amd64 $ ./alertmanager
Alertmanager 启动后默认可以通过 http://localhost:9093/
来访问,但是现在还看不到告警,因为我们还没有把 Alertmanager 配置到 Prometheus 中,我们回到 Prometheus 的配置文件 prometheus.yml
,添加下面几行:
alerting: alertmanagers: - scheme: http static_configs: - targets: - "192.168.0.107:9093"
这个配置告诉 Prometheus,当发生告警时,将告警信息发送到 Alertmanager,Alertmanager 的地址为 http://192.168.0.107:9093
。也可以使用命名行的方式指定 Alertmanager:
$ ./prometheus -alertmanager.url=http://192.168.0.107:9093
这个时候再访问 Alertmanager,可以看到 Alertmanager 已经接收到告警了:
下面的问题就是如何让 Alertmanager 将告警信息发送给我们了,我们打开默认的配置文件 alertmanager.ym
:
global: resolve_timeout: 5m route: group_by: ['alertname'] group_wait: 10s group_interval: 10s repeat_interval: 1h receiver: 'web.hook' receivers: - name: 'web.hook' webhook_configs: - url: 'http://127.0.0.1:5001/' inhibit_rules: - source_match: severity: 'critical' target_match: severity: 'warning' equal: ['alertname', 'dev', 'instance']
参考 官方的配置手册 了解各个配置项的功能,其中 global 块表示一些全局配置;route 块表示通知路由,可以根据不同的标签将告警通知发送给不同的 receiver,这里没有配置 routes 项,表示所有的告警都发送给下面定义的 web.hook 这个 receiver;如果要配置多个路由,可以参考 这个例子:
routes: - receiver: 'database-pager' group_wait: 10s match_re: service: mysql|cassandra - receiver: 'frontend-pager' group_by: [product, environment] match: team: frontend
紧接着,receivers 块表示告警通知的接收方式,每个 receiver 包含一个 name 和一个 xxx_configs,不同的配置代表了不同的接收方式,Alertmanager 内置了下面这些接收方式:
## wechat_configswebhook_config
雖然接收方式很豐富,但在國內,其中大多數接收方式都很少使用。最常用到的,莫屬
email_config### 和 ###webhook_config###,另外 ###wechat_configs### 可以支援使用微信來告警,也是相當符合國情的了。 ######其實告警的通知方式是很難做到面面俱到的,因為訊息軟體各種各樣,每個國家還可能不同,不可能完全覆蓋到,所以Alertmanager 已經決定不再添加新的receiver了,而是推薦使用webhook 來整合自訂的接收方式。可以參考 這些整合的例子,譬如 將釘子連接到 Prometheus AlertManager WebHook。 ###到這裡,我們已經學習了Prometheus 的大多數功能,結合Prometheus Grafana Alertmanager 完全可以建立一套非常完整的監控系統。不過在真正使用時,我們會發現更多的問題。
由於Prometheus 是透過Pull 的方式主動獲取監控數據,所以需要手動指定監控節點的列表,當監控的節點增多之後,每次增加節點都需要更改設定文件,非常麻煩,這個時候就需要透過服務發現(service discovery,SD)機制去解決。
Prometheus 支援多種服務發現機制,可以自動取得要收集的targets,可以參考這裡,包含的服務發現機制包括:azure、consul、dns、ec2、openstack、file、gce、kubernetes、marathon 、triton、zookeeper(nerve、serverset),設定方法可以參考手冊的Configuration 頁面。可以說 SD 機制是非常豐富的,但目前由於開發資源有限,已經不再開發新的 SD 機制,只對基於檔案的 SD 機制進行維護。
關於服務發現網上有很多教程,譬如Prometheus 官方博客中這篇文章Advanced Service Discovery in Prometheus 0.14.0 對此有一個比較系統的介紹,全面的講解了relabeling 配置,以及如何使用DNS -SRV、Consul 和文件來做服務發現。
另外,官網也提供了 一個基於文件的服務發現的入門例子,Julius Volz 寫的 Prometheus workshop 入門教程中也 使用了 DNS-SRV 來當服務發現。另外,微服務系列面試題和答案全部整理好了,微信搜尋網路架構師,在後台發送:2T,可以線上閱讀。
無論是 Prometheus 的配置還是 Alertmanager 的配置,都沒有提供 API 供我們動態的修改。一個很常見的場景是,我們需要基於Prometheus 做一套可自訂規則的告警系統,使用者可根據自己的需求在頁面上建立修改或刪除告警規則,或是修改告警通知方式和聯絡人,正如在Prometheus Google Groups 裡的這個使用者的問題:How to dynamically add alerts rules in rules.conf and prometheus yml file via API or something?
不過遺憾的是,Simon Pasquier 在下面說到,目前並沒有這樣的API,而且以後也沒有這樣的計劃來開發這樣的API,因為這樣的功能更應該交給譬如Puppet、Chef 、Ansible、Salt 這樣的設定管理系統。
這篇部落格參考了網路上大量關於Prometheus 的中文資料,有文檔,也有博客,例如1046102779 的Prometheus 非官方中文手冊,宋佳洋的電子書《Prometheus 實戰》,在這裡對這些原作者表示敬意。在 Prometheus 官方文件的 Media 頁面,也提供了許多學習資源。
關於Prometheus,還有非常重要的一部分內容這篇部落格沒有涉及到,正如博客一開頭所講的,Prometheus 是繼Kubernetes 之後第二個加入CNCF 的項目,Prometheus 和Docker、Kubernetes 的結合非常緊密,使用Prometheus 作為Docker 和Kubernetes 的監控系統也越來越主流。
關於Docker 的監控,可以參考官網的一篇指南:Monitoring Docker container metrics using cAdvisor,它介紹瞭如何使用cAdvisor 來對容器進行監控;不過Docker 現在也開始原生支援Prometheus 的監控了,參考Docker 的官方文件Collect Docker metrics with Prometheus;關於Kubernetes 的監控,Kubernetes 中文社群裡有不少關於Promehtheus 的資源,另外,《如何以優雅的姿勢監控Kubernetes》這本電子書也對Kubernetes 的監控有一個比較全面的介紹。
最近兩年 Prometheus 的發展非常迅速,社群也非常活躍,國內研究 Prometheus 的人也越來越多。隨著微服務,DevOps,雲端運算,雲端原生等概念的普及,越來越多的企業開始使用Docker 和Kubernetes 來建立自己的系統和應用,像Nagios 和Cacti 這樣的老牌監控系統會變得越來越不適用,相信Prometheus 最終會發展成一個最適合雲端環境的監控系統。
上文提到 Prometheus 是一款基於時序資料庫的監控系統,時序資料庫常簡寫為 TSDB(Time Series Database)。許多流行的監控系統都在使用時序資料庫來保存數據,這是因為時序資料庫的特性和監控系統不謀而合。
#DB-Engines 上有一個關於時序資料庫的排名,下面是排名前面的幾個(2018年10月):
#另外,liubin 在他的部落格上寫了一系列關於時序資料庫的文章:時序列資料庫武斗大會,推薦。
以上是號稱下一代監控系統,來看看它有多強!的詳細內容。更多資訊請關注PHP中文網其他相關文章!