• 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

  • 相关阅读:
    「JXOI2018」游戏
    「CTSC2018」假面
    CodeForces
    CodeForces
    [Lydsy1710月赛] 小B的数字
    OpenJ_Bailian
    [SDOI2010] 地精部落
    CodeForces
    CodeForces
    [NOI2009] 管道取珠
  • 原文地址:https://www.cnblogs.com/Zero-Jo/p/14714669.html
Copyright © 2020-2023  润新知