prometheus--監控工具


1.背景

  prometheus是一個以神名為名的工具,有"先知先覺"的寓意。prometheus是一套開源的系統監控報警框架,十分符合它的定位。它啟發於 Google 的 borgmon 監控系統,由工作在 SoundCloud 的 google 前員工在 2012 年創建,作為社區開源項目進行開發,並於 2015 年正式發布。prometheus,不是一個單一工具,它是由多個組件組合起來的工具。對剛剛開始學習的同學可以先看一下這邊文章,讓大家對prometheus有一個基本了解: https://www.cnblogs.com/linuxk/p/12017580.html(非常推薦

2.基礎架構

  

 

Prometheus 由多個組件組成,但是其中許多組件是可選的:

服務端:

  • Prometheus Server服務段組件,它是 Prometheus 核心組件,用於收集指標和存儲時間序列數據,並提供查詢接口。
  • push gateway網關組件,可以將它視為一個特殊 node_exporter 組件主要用於臨時性的 jobs。由於這類 jobs 存在時間較短,可能在 Prometheus 來 pull 之前就消失了。對此Jobs定時將指標push到pushgateway,再由Prometheus Server從Pushgateway上pull,根據業務需要可配置

客戶端:

  • node_exporter客戶端收集器組件,用於暴露已有的第三方服務的 metrics(指標) 給 Prometheus。
  • alertmanager監控告警組件,從 Prometheus server 端接收到 alerts 后,會進行去除重復數據,分組,並路由到對收的接受方式,發出報警。常見的接收方式有:電子郵件,pagerduty,OpsGenie, webhook 等,根據業務需要可配置
  • Web UI視圖組件,Prometheus內置一個簡單的Web控制台,可以查詢指標,查看配置信息或者Service Discovery等,實際工作中,查看指標或者創建儀表盤通常使用Grafana,Prometheus作為Grafana的數據源,根據業務需要可配置。
  • client Library客戶端服務(例如Go,Python,Java等),為需要監控的服務產生相應的/metrics並暴露給Prometheus Server。目前已經有很多的軟件原生就支持Prometheus,提供/metrics,可以直接使用。對於像操作系統已經不提供/metrics,可以使用exporter,或者自己開發exporter來提供/metrics服務,根據業務需要可配置

3.Prometheus獲取指標方式

prometheus客戶端主要由2種數據采集的方式:

pull(拉取形式):指的是客戶端(被監控主機)先安裝各類已有的exporters在系統上,exporters以守護進程的模式運行,並開始采集數據,exporters本身也是一個http_server,可以對http請求作出響應,並返回K/V數據,也就是metrics。prometheus通過用pull的方式(HTTP_GET)去訪問每個節點上的exporter並采集回需要的數據。

push(推送的形式):指的是客戶端(或服務端)安裝官方的pushgateway插件,然后通過我們自行編寫的各種腳本,將監控數據組織成K/V的形式(metrics形式)發送給pushgateway,而后pushgateway再推送給prometheus,這里需要注意的是pushgateway不一定要安裝在被監控端,也可以安裝在服務端,甚至是一台不相關的主機上,換句話來說,它只是一個中間轉發的媒介。 

4.執行流程

 short_lived:  就是本地自定義腳本,它會定時將指標信息推送到pushgateway。感覺pushgateway就是一個特殊的node_exporter。具體使用方式:http://www.linuxe.cn/post-506.html

5.metrics指標類型

Counter:  counter 是一個累積計數的指標,僅支持增加或者重置為0(只增不減 )。例如:可以用來統計服務請求的數量,任務完成數量,或者出錯的數量。

Gauge:  gauge是一個純數值型的能夠經常進行增加或者減少的指標。例如用來做溫度的計數,內存的使用,同樣也可以用來使用計算服務請求數量。

Histogram:直方圖,histogram 在一段時間內進行采樣,並能夠對指定區間以及總數進行統計.

Summary: summary與histogram類似,用於表示一段時間內的采樣數據,但它直接存儲了分位數,而不是通過區間來計算。

6.埋點

 spring-actuator做度量統計收集,使用Prometheus(普羅米修斯)進行數據收集,Grafana(增強ui)進行數據展示,用於監控生成環境機器的性能指標和業務數據指標。一般,我們叫這樣的操作為”埋點”。SpringBoot中的依賴spring-actuator中集成的度量統計API使用的框架是Micrometer,官網是Micrometer.io。

1. 引入Prometheus metrics 包

<!-- https://mvnrepository.com/artifact/io.micrometer/micrometer-core -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<version>1.6.6</version>
</dependency>

2. 以使用http client 為例。 

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.DistributionSummary;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;

/**
 * 
 * @date 2021-04-29 2:59 下午
 */
public class Test3 {

    private static final MeterRegistry registry = new SimpleMeterRegistry();

    public static void main(String[] args) {
        String[] tags = formattedTag(builderTag());

        //折線圖
        new Test3().counter("HTTP_SUCCESS_COUNT","http請求成功次數",tags);

        //折線圖
        new Test3().timer("RT",10000L,"http請求響應時間",tags);

        //樹狀圖
        GaugeDemo gaugeDemo = new GaugeDemo();
        gaugeDemo.setGaugeMetricsName("xxxx");
        gaugeDemo.setMetrics(1);
        new Test3().gauge("Memory_metrics_test",gaugeDemo,"內存變化指標",tags);

        // 響應成功占比 : 餅狀圖
        new Test3().summary("summary_http_success",0.98d,"響應成功占比",100,tags);
    }

    /**
     * 使用者也可以自行繼承MeterRegistry去實現自定義的MeterRegistry。SimpleMeterRegistry適合做調試的時候使用,它的簡單使用方式如下
     * @param name 指標key
     * @param desc 基礎單位
     * @param tags 標簽信息
     * 折線圖
     */
    private void counter(String name,String desc,String... tags){
        Counter counter = Counter.builder(name)
                .description(desc)
                //標簽
                .tags(tags)
                //綁定的MeterRegistry
                .register(registry);
        //數值加一,原子操作
        counter.increment();

    }

    /**
     * 時間埋點
     * @param name 指標key
     * @param nanoSeconds 響應時間
     * @param desc 描述
     * @param tags 標簽信息
     * 折線圖
     */
    private void timer(String name,Long nanoSeconds,String desc,String... tags){
        Timer timer = Timer.builder(name)
                .description(desc)
                //標簽
                .tags(tags)
                //綁定的MeterRegistry
                .register(registry);
        //數值加一,原子操作
        timer.record(nanoSeconds, TimeUnit.NANOSECONDS);
    }

    /**
     * 數值埋點是個 Gauge, 可以用在查看某個場景單位時間內的變化的情形。
     * 樹狀圖
     * @param name 指標key
     * @param gaugeDemo 指標對象
     * @param desc 指標描述信息
     * @param tags 標簽信息
     */
    private void gauge(String name,GaugeDemo gaugeDemo,String desc,String... tags){
        Gauge gauge = Gauge.builder(name,gaugeDemo,GaugeDemo::getMetrics)
                .description(desc)
                //標簽
                .tags(tags)
                //綁定的MeterRegistry
                .register(registry);

    }

    /**
     * Summary(摘要)主要用於跟蹤事件的分布,在Micrometer中,對應的類是DistributionSummary(分發摘要)。它的使用方式和Timer十分相似,但是它的記錄值並不依賴於時間單位。
     * 餅狀圖
     * 例如: 某個指標的百分比
     * @param name 指標key
     * @param desc 描述信息
     * @param scale 將記錄到分布摘要的值乘以比例因子。 可配置
     * @param tags 標簽信息
     * @param value 計算值
     */
    private void summary(String name,double value,String desc ,double scale,String... tags ){
        DistributionSummary summary = DistributionSummary
                .builder(name)
                .description(desc)
                .tags(tags)
                .scale(scale)
                .register(registry);
        summary.record(value);
    }


    private static class GaugeDemo{
        /**
         * 指標名
         */
        private String gaugeMetricsName;

        /**
         * 度量指標
         */
        private Integer metrics;

        public String getGaugeMetricsName() {
            return gaugeMetricsName;
        }

        public void setGaugeMetricsName(String gaugeMetricsName) {
            this.gaugeMetricsName = gaugeMetricsName;
        }

        public Integer getMetrics() {
            return metrics;
        }

        public void setMetrics(Integer metrics) {
            this.metrics = metrics;
        }
    }

    private static String[] formattedTag(Map<String,String> tag){
        String[] result = new String[tag.size() * 2];
        int i = 0;
        for (Map.Entry<String, String> entry : tag.entrySet()){
            result[i] = entry.getKey();
            i++;
            result[i] = entry.getValue();
            i++;
        }
        return result;
    }

    private static Map<String,String> builderTag(){
        /**
         * 1、Tag的值必須不為null。
         *
         * 2、Micrometer中,Tag必須成對出現,也就是Tag必須設置為偶數個,實際上它們以Key=Value的形式存在
         */
        HashMap<String, String> tags = new HashMap<>();
        tags.put("url","wwww.baidu.com");
        tags.put("code","200");
        tags.put("method","POST");
        return tags;
    }
}

 當然,還有其他類型,有其他擴展類型。就不一一舉例了。

效果顯示

我們的項目是基於spring cloud組件來處理的,我們可以通過訪問這個地址就可以看到我們上報給prometheus的信息

http://服務ip:服務端口/actuator/prometheus

將會得到如下信息:

-- 描述信息: 請求響應時間 指標

# HELP fusion_http_response_time_seconds response.time
-- 統計的類型 # TYPE fusion_http_response_time_seconds summary

-- 指標key: RT ,{} 這個括號中的就是你寫入的 tag 信息, 最后面一個是指標
RT
{bizCode
="0",endpoint="[GET]/actuator/health",method="GET",mode="servlet",status="200",type="",} 58331.0

 

7.Prometheus本地存儲

TSDB

Prometheus本地儲存使用它自己寫的TSDB(時序數據庫)

時序數據庫全稱為時間序列數據庫。時間序列數據庫主要用於指處理帶時間標簽(按照時間的順序變化,即時間序列化)的數據,帶時間標簽的數據也稱為時間序列數據。主要用於存儲周期性的采集各種實時監控信息。

目錄結構

./data ├── 01BKGV7JBM69T2G1BGBGM6KB12 │ └── meta.json ├── 01BKGTZQ1SYQJTR4PB43C8PD98 │ ├── chunks │ │ └── 000001 │ ├── tombstones │ ├── index │ └── meta.json ├── 01BKGTZQ1HHWHV8FBJXW1Y3W0K │ └── meta.json ├── 01BKGV7JC0RY8A6MACW02A2PJD │ ├── chunks │ │ └── 000001 │ ├── tombstones │ ├── index │ └── meta.json └── wal ├── 00000002 └── checkpoint.00000
首先,block 在這里是一個數據塊,每個數據塊相對獨立,由一個目錄組成,該目錄里包含:一個或者多個 chunk 文件(保存 timeseries 數據)、一個 metadata文件、一個 index 文件(通過 metric name 和 labels 查找 timeseries 數據在 chunk 文件的位置)。

儲存原理(write)

Prometheus 按2小時一個 block 進行存儲,最新寫入的數據保存在內存 block 中,達到2小時后寫入磁盤。為了防止程序崩潰導致數據丟失,實現了 WAL(write-ahead-log)機制,啟動時會以寫入日志(WAL)的方式來實現重播,從而恢復數據。

8.其他監控工具對比

 

 

引用

https://www.sohu.com/a/342733264_198222

https://www.cnblogs.com/linuxk/p/12017580.html

http://www.linuxe.cn/post-506.html

https://www.freesion.com/article/5362527244/

https://www.jianshu.com/p/a80cc630fa73

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM