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

簡介

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

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

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é)構(gòu):

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)存大写隆)都是Gauge類型的監(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ù)呢? 這個時候我們就可以使用位移操作笤休,位移操作的關(guān)鍵字為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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市虾标,隨后出現(xiàn)的幾起案子寓盗,更是在濱河造成了極大的恐慌,老刑警劉巖璧函,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件傀蚌,死亡現(xiàn)場離奇詭異,居然都是意外死亡蘸吓,警方通過查閱死者的電腦和手機善炫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來库继,“玉大人箩艺,你說我怎么就攤上這事∠芴眩” “怎么了艺谆?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拜英。 經(jīng)常有香客問我静汤,道長,這世上最難降的妖魔是什么居凶? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任虫给,我火速辦了婚禮,結(jié)果婚禮上侠碧,老公的妹妹穿的比我還像新娘抹估。我一直安慰自己,他們只是感情好弄兜,可當我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布棋蚌。 她就那樣靜靜地躺著,像睡著了一般挨队。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蒿往,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天盛垦,我揣著相機與錄音,去河邊找鬼瓤漏。 笑死腾夯,一個胖子當著我的面吹牛颊埃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蝶俱,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼班利,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了榨呆?” 一聲冷哼從身側(cè)響起罗标,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎积蜻,沒想到半個月后闯割,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡竿拆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年宙拉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丙笋。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡谢澈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出御板,到底是詐尸還是另有隱情锥忿,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布稳吮,位于F島的核電站缎谷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏灶似。R本人自食惡果不足惜列林,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望酪惭。 院中可真熱鬧希痴,春花似錦、人聲如沸春感。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鲫懒。三九已至嫩实,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間窥岩,已是汗流浹背甲献。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留颂翼,地道東北人晃洒。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓慨灭,卻偏偏與公主長得像,于是被迫代替她去往敵國和親球及。 傳聞我的和親對象是個殘疾皇子氧骤,可洞房花燭夜當晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容