prometheus監(jiān)控利器(一)

簡介

眾所周知,prometheus(普羅米修斯)是微服務監(jiān)控領域的新星,這幾年發(fā)展迅猛。之前用過一些框架自帶metrics,接觸過prometheus,這次準備系統(tǒng)的深入研究一下相關監(jiān)控方案。

先看看prometheus及周邊生態(tài)的結(jié)構圖:

36-01.png

環(huán)境搭建

按照慣例,先把環(huán)境搭起來,hello world跑通再說。

docker-compose.yaml

version: '3'

services:
  prometheus:
    image: prom/prometheus
    volumes:
      - "./prometheus/prometheus.yaml:/etc/prometheus/prometheus.yml"
      - "./prometheus/data:/prometheus"
      - "./prometheus/rule.yaml:/etc/prometheus/rule.yml"
    ports:
    - "9090:9090"

  server1:
    image: phpswoole/swoole:php7.3
    volumes:
    - "./server1:/app"
    ports:
    - "9502:9502"
    command: php /app/server.php start

  grafana:
    image: grafana/grafana
    ports:
    - '3000:3000'
    volumes:
    - "./grafana/data:/var/lib/grafana"

  alertmanager:
    image: prom/alertmanager
    ports:
    - '9093:9093'
    volumes:
    - "./alertmanager/alert.yaml:/etc/alertmanager/alertmanager.yml"
    - "./alertmanager/data:/alertmanager"
    - "./alertmanager/templates:/templates"

目錄結(jié)構:

36-02.png

metrics:

<?php

use Prometheus\CollectorRegistry;
use Prometheus\RenderTextFormat;
use Prometheus\Storage\InMemory;
use Swoole\Coroutine\Http\Server;
use function Swoole\Coroutine\run;

require_once __DIR__ . '/vendor/autoload.php';

run(function () {

    $registry = new CollectorRegistry(new InMemory());

    $server = new Server('0.0.0.0', 9502, false);

    $server->set([
        'mode' => SWOOLE_BASE,
        'worker_num' => 1
    ]);

    $GLOBALS['gauge'] = 1;

    $server->handle('/metrics', function ($request, $response)use ($registry) {
        $registry->getOrRegisterCounter('','some_quick_counter','just a quick counter')
            ->inc();
        $registry->getOrRegisterGauge('','some_gauge','it sets',['type'])
            ->set($GLOBALS['gauge'],['blue']);
        $registry->getOrRegisterHistogram('','some_histogram','it observes',['color'],[0.1,2,3,3.5,4,5,6,7,8,9])
            ->observe(random_int(1,10),['red']);

        $render = new RenderTextFormat();
        $metrics = $render->render($registry->getMetricFamilySamples());

        $response->header('Content-Type',RenderTextFormat::MIME_TYPE);
        $response->end($metrics);
    });

    $server->handle('/reset',function ($request,$response)use ($registry){
        $GLOBALS['gauge'] = 0;
        $response->end($GLOBALS['gauge']);
    });

    $server->start();
});

用 swoole server 借助 prometheus client 實現(xiàn) metrics 邏輯,配置 pull job 即可。

prometheus 配置:

global:
  scrape_interval: 10s
  evaluation_interval: 10s
  scrape_timeout: 10s
  external_labels:
    prom: 'a'

scrape_configs:
  - job_name: 'purelight'
    static_configs:
      - targets: ['server1:9502']
  - job_name: 'prometheus'
    static_configs:
      - targets: ['127.0.0.1:9090']

alerting:
  alertmanagers:
    - static_configs:
        - targets: ['alertmanager:9093']

rule_files:
  - "/etc/prometheus/rule.yml"

這樣,prometheus 就會每10s抓取server1的metrics,以及prometheus自身的metrcis,另外,alertmanagers配置告警。

啟動:docker-compose up -d

Prometheus

訪問:http://127.0.0.1:9502/metrics

36-03.png

這就是 prometheus pull 模式抓取 metrics 信息的消息大致格式。

數(shù)據(jù)類型

prometheus 數(shù)據(jù)組成:

  • 指標(metric):metric name和描述當前樣本特征的labelsets;

  • 時間戳(timestamp):一個精確到毫秒的時間戳;

  • 樣本值(value): 一個float64的浮點型數(shù)據(jù)表示當前樣本的值。

指標格式:<metric name>{<label name>=<label value>, ...}

metric 又分4種類型(metric type):Counter(計數(shù)器)、Gauge(儀表盤)、Histogram(直方圖)、Summary(摘要)。

Counter

Counter類型的指標其工作方式和計數(shù)器一樣,只增不減(除非系統(tǒng)發(fā)生重置)。常見的監(jiān)控指標,如http_requests_total,node_cpu都是Counter類型的監(jiān)控指標。 一般在定義Counter類型指標的名稱時推薦使用_total作為后綴。

php client 示例:

$registry = new CollectorRegistry(new InMemory());

$counter = $registry->getOrRegisterCounter('','some_quick_counter','just a quick counter');
$counter->inc();
Gauge:

與Counter不同,Gauge類型的指標側(cè)重于反應系統(tǒng)的當前狀態(tài)。因此這類指標的樣本數(shù)據(jù)可增可減。常見指標如:node_memory_MemFree(主機當前空閑的內(nèi)容大?。?、node_memory_MemAvailable(可用內(nèi)存大?。┒际荊auge類型的監(jiān)控指標。

php client 示例:

$gauge = $registry->getOrRegisterGauge('','some_gauge','it sets',['type']);
$gauge->set(2.5, ['blue']);
Histogram和Summary分析數(shù)據(jù)分布情況

除了Counter和Gauge類型的監(jiān)控指標以外,Prometheus還定義了Histogram和Summary的指標類型。Histogram和Summary主用用于統(tǒng)計和分析樣本的分布情況。

在大多數(shù)情況下人們都傾向于使用某些量化指標的平均值,例如CPU的平均使用率、頁面的平均響應時間。這種方式的問題很明顯,以系統(tǒng)API調(diào)用的平均響應時間為例:如果大多數(shù)API請求都維持在100ms的響應時間范圍內(nèi),而個別請求的響應時間需要5s,那么就會導致某些WEB頁面的響應時間落到中位數(shù)的情況,而這種現(xiàn)象被稱為長尾問題。

為了區(qū)分是平均的慢還是長尾的慢,最簡單的方式就是按照請求延遲的范圍進行分組。例如,統(tǒng)計延遲在010ms之間的請求數(shù)有多少而1020ms之間的請求數(shù)又有多少。通過這種方式可以快速分析系統(tǒng)慢的原因。Histogram和Summary都是為了能夠解決這樣問題的存在,通過Histogram和Summary類型的監(jiān)控指標,我們可以快速了解監(jiān)控樣本的分布情況。

例如,指標prometheus_tsdb_wal_fsync_duration_seconds的指標類型為Summary。 它記錄了Prometheus Server中wal_fsync處理的處理時間,通過訪問Prometheus Server的/metrics地址,可以獲取到以下監(jiān)控樣本數(shù)據(jù):

# HELP prometheus_tsdb_wal_fsync_duration_seconds Duration of WAL fsync.
# TYPE prometheus_tsdb_wal_fsync_duration_seconds summary
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.5"} 0.012352463
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.9"} 0.014458005
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.99"} 0.017316173
prometheus_tsdb_wal_fsync_duration_seconds_sum 2.888716127000002
prometheus_tsdb_wal_fsync_duration_seconds_count 216

從上面的樣本中可以得知當前Prometheus Server進行wal_fsync操作的總次數(shù)為216次,耗時2.888716127000002s。其中中位數(shù)(quantile=0.5)的耗時為0.012352463,9分位數(shù)(quantile=0.9)的耗時為0.014458005s。

在Prometheus Server自身返回的樣本數(shù)據(jù)中,我們還能找到類型為Histogram的監(jiān)控指標prometheus_tsdb_compaction_chunk_range_bucket。

# HELP prometheus_tsdb_compaction_chunk_range Final time range of chunks on their first compaction
# TYPE prometheus_tsdb_compaction_chunk_range histogram
prometheus_tsdb_compaction_chunk_range_bucket{le="100"} 0
prometheus_tsdb_compaction_chunk_range_bucket{le="400"} 0
prometheus_tsdb_compaction_chunk_range_bucket{le="1600"} 0
prometheus_tsdb_compaction_chunk_range_bucket{le="6400"} 0
prometheus_tsdb_compaction_chunk_range_bucket{le="25600"} 0
prometheus_tsdb_compaction_chunk_range_bucket{le="102400"} 0
prometheus_tsdb_compaction_chunk_range_bucket{le="409600"} 0
prometheus_tsdb_compaction_chunk_range_bucket{le="1.6384e+06"} 260
prometheus_tsdb_compaction_chunk_range_bucket{le="6.5536e+06"} 780
prometheus_tsdb_compaction_chunk_range_bucket{le="2.62144e+07"} 780
prometheus_tsdb_compaction_chunk_range_bucket{le="+Inf"} 780
prometheus_tsdb_compaction_chunk_range_sum 1.1540798e+09
prometheus_tsdb_compaction_chunk_range_count 780

與Summary類型的指標相似之處在于Histogram類型的樣本同樣會反應當前指標的記錄的總數(shù)(以_count作為后綴)以及其值的總量(以_sum作為后綴)。不同在于Histogram指標直接反應了在不同區(qū)間內(nèi)樣本的個數(shù),區(qū)間通過標簽len進行定義。

同時對于Histogram的指標,我們還可以通過histogram_quantile()函數(shù)計算出其值的分位數(shù)。不同在于Histogram通過histogram_quantile函數(shù)是在服務器端計算的分位數(shù)。 而Sumamry的分位數(shù)則是直接在客戶端計算完成。因此對于分位數(shù)的計算而言,Summary在通過PromQL進行查詢時有更好的性能表現(xiàn),而Histogram則會消耗更多的資源。反之對于客戶端而言Histogram消耗的資源更少。在選擇這兩種方式時用戶應該按照自己的實際場景進行選擇。

PromQL

瞬時向量 vs 區(qū)間向量

metric name 默認就是瞬時向量,代表當前最新一條數(shù)據(jù);區(qū)間向量是過去一段時間的多條數(shù)據(jù),使用方法是 metric name 后跟 [5m] 這種時間標志,支持:s - 秒,m - 分鐘,h - 小時,d - 天,w - 周,y - 年。

時間位移

在瞬時向量表達式或者區(qū)間向量表達式中,都是以當前時間為基準。而如果我們想查詢,5分鐘前的瞬時樣本數(shù)據(jù),或昨天一天的區(qū)間內(nèi)的樣本數(shù)據(jù)呢? 這個時候我們就可以使用位移操作,位移操作的關鍵字為offset。

http_request_total{} offset 5m
http_request_total{}[1d] offset 1d
操作符

支持數(shù)學運算符:+ (加法),- (減法),* (乘法),/ (除法),% (求余),^ (冪運算)。

支持布爾運算符:== (相等),!= (不相等),> (大于),< (小于),>= (大于等于),<= (小于等于)。

函數(shù)

sum (求和),min (最小值),max (最大值),avg (平均值),stddev (標準差),stdvar (標準方差),count (計數(shù)),count_values (對value進行計數(shù)),bottomk (后n條時序),topk (前n條時序),quantile (分位數(shù)) ......

PromQL 的發(fā)揮主要是在 Grafana 圖表繪制中。

Grafana

Grafana 主要用于可視化圖表繪制,內(nèi)置支持 prometheus 數(shù)據(jù)源。

簡單看下如何添加一個 counter 類型的數(shù)據(jù)圖表繪制方法:

36-04.png

非常簡單,但這只是鳳毛棱角,grafana+prometheus 還支持更多的圖表類型。

應用層

工具花里胡哨的太多,對于項目來說,最重要的還是做好 metrics 統(tǒng)計指標,借助 prometheus client ,提供 /metrics http endpoint,讓 prometheus 主動定時 pull 。

prometheus 除了 pull 模式,還支持客戶端主動 push 的模式,這個用于客戶端不方便開放 http 端口的情況。

下次探討 alertmanager 以及 prometheus 更多內(nèi)容……

2021-07-12

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容