MetricsSystem

2023-05-16

Metrics,我们听到的太多了,熟悉大数据系统的不可能没听说过metrics,当我们需要为某个系统某个服务做监控、做统计,就需要用到Metrics。

举个例子,一个图片压缩服务:

  1. 每秒钟的请求数是多少(TPS)?
  2. 平均每个请求处理的时间?
  3. 请求处理的最长耗时?
  4. 等待处理的请求队列长度?

又或者一个缓存服务:

  1. 缓存的命中率?
  2. 平均查询缓存的时间?

基本上每一个服务、应用都需要做一个监控系统,这需要尽量以少量的代码,实现统计某类数据的功能。

以 Java 为例,目前最为流行的 metrics 库是来自 Coda Hale 的 dropwizard/metrics,该库被广泛地应用于各个知名的开源项目中。例如 Hadoop,Kafka,Spark,JStorm 中。

本文就结合范例来主要介绍下 dropwizard/metrics 的概念和用法。

Maven 配置

我们需要在pom.xml中依赖 metrics-core 包:


<dependencies>
    <dependency>
        <groupId>io.dropwizard.metrics</groupId>
        <artifactId>metrics-core</artifactId>
        <version>${metrics.version}</version>
    </dependency>
</dependencies>  

Metric Registries

MetricRegistry类是Metrics的核心,它是存放应用中所有metrics的容器。也是我们使用 Metrics 库的起点。


MetricRegistry registry = new MetricRegistry();
  

每一个 metric 都有它独一无二的名字,Metrics 中使用句点名字,如 com.example.Queue.size。当你在 com.example.Queue 下有两个 metric 实例,可以指定地更具体:com.example.Queue.requests.size 和 com.example.Queue.response.size 。使用MetricRegistry类,可以非常方便地生成名字


MetricRegistry.name(Queue.class, "requests", "size")
MetricRegistry.name(Queue.class, "responses", "size")
  

Metrics 数据展示

Metircs 提供了 Report 接口,用于展示 metrics 获取到的统计数据。metrics-core中主要实现了四种 reporter:JMX, console, SLF4J, 和 CSV。 在本文的例子中,我们使用 ConsoleReporter 。

五种 Metrics 类型

Gauges 

最简单的度量指标,只有一个简单的返回值,或者叫瞬时状态,例如,我们想衡量一个待处理队列中任务的个数,代码如下:


public class GaugeTest {

    public static Queue<String> q = new LinkedList<String>();

    public static void main(String[] args) throws InterruptedException {
        MetricRegistry registry = new MetricRegistry();
        ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build();
        reporter.start(1, TimeUnit.SECONDS);

        registry.register(MetricRegistry.name(GaugeTest.class, "queue", "size"), 
        new Gauge<Integer>() {

            public Integer getValue() {
                return q.size();
            }
        });

        while(true){
            Thread.sleep(1000);
            q.add("Job-xxx");
        }
    }
}
  

运行之后的结果如下:


-- Gauges ------------------------------------------------
com.alibaba.wuchong.metrics.GaugeTest.queue.size
             value = 6
  

其中第7行和第8行添加了ConsoleReporter,可以每秒钟将度量指标打印在屏幕上,理解起来会更清楚。

但是对于大多数队列数据结构,我们并不想简单地返回queue.size(),因为java.utiljava.util.concurrent中实现的#size()方法很多都是 O(n) 的复杂度,这会影响 Gauge 的性能。

Counters

Counter 就是计数器,Counter 只是用 Gauge 封装了 AtomicLong 。我们可以使用如下的方法,使得获得队列大小更加高效。


public class CounterTest {

    public static Queue<String> q = new LinkedBlockingQueue<String>();

    public static Counter pendingJobs;

    public static Random random = new Random();

    public static void addJob(String job) {
        pendingJobs.inc();
        q.offer(job);
    }

    public static String takeJob() {
        pendingJobs.dec();
        return q.poll();
    }

    public static void main(String[] args) throws InterruptedException {
        MetricRegistry registry = new MetricRegistry();
        ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build();
        reporter.start(1, TimeUnit.SECONDS);

        pendingJobs = registry.counter(MetricRegistry.name(Queue.class,"pending-jobs","size"));

        int num = 1;
        while(true){
            Thread.sleep(200);
            if (random.nextDouble() > 0.7){
                String job = takeJob();
                System.out.println("take job : "+job);
            }else{
                String job = "Job-"+num;
                addJob(job);
                System.out.println("add job : "+job);
            }
            num++;
        }
    }
}
  

运行之后的结果大致如下:


add job : Job-15
add job : Job-16
take job : Job-8
take job : Job-10
add job : Job-19
15-8-1 16:11:31 ============================================
-- Counters ----------------------------------------------
java.util.Queue.pending-jobs.size
             count = 5
  

Meters

Meter度量一系列事件发生的速率(rate),例如TPS。Meters会统计最近1分钟,5分钟,15分钟,还有全部时间的速率。


public class MeterTest {

    public static Random random = new Random();

    public static void request(Meter meter){
        System.out.println("request");
        meter.mark();
    }

    public static void request(Meter meter, int n){
        while(n > 0){
            request(meter);
            n--;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MetricRegistry registry = new MetricRegistry();
        ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build();
        reporter.start(1, TimeUnit.SECONDS);

        Meter meterTps = registry.meter(MetricRegistry.name(MeterTest.class,"request","tps"));

        while(true){
            request(meterTps,random.nextInt(5));
            Thread.sleep(1000);
        }

    }
}
  

运行结果大致如下:


request
15-8-1 16:23:25 ============================================

-- Meters ------------------------------------------------
com.alibaba.wuchong.metrics.MeterTest.request.tps
             count = 134
         mean rate = 2.13 events/second
     1-minute rate = 2.52 events/second
     5-minute rate = 3.16 events/second
    15-minute rate = 3.32 events/second
  

注:非常像 Unix 系统中 uptime 和 top 中的 load。

Histograms

Histogram统计数据的分布情况。比如最小值,最大值,中间值,还有中位数,75百分位, 90百分位, 95百分位, 98百分位, 99百分位, 和 99.9百分位的值(percentiles)。

比如request的大小的分布:


public class HistogramTest {
    public static Random random = new Random();

    public static void main(String[] args) throws InterruptedException {
        MetricRegistry registry = new MetricRegistry();
        ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build();
        reporter.start(1, TimeUnit.SECONDS);

        Histogram histogram = new Histogram(new ExponentiallyDecayingReservoir());
        registry.register(MetricRegistry.name(HistogramTest.class, "request", "histogram"), histogram);
        
        while(true){
            Thread.sleep(1000);
            histogram.update(random.nextInt(100000));
        }

    }
}
  

运行之后结果大致如下:


-- Histograms --------------------------------------------
java.util.Queue.queue.histogram
             count = 56
               min = 1122
               max = 99650
              mean = 48735.12
            stddev = 28609.02
            median = 49493.00
              75% <= 72323.00
              95% <= 90773.00
              98% <= 94011.00
              99% <= 99650.00
            99.9% <= 99650.00
  

Timers

Timer其实是 Histogram 和 Meter 的结合, histogram 某部分代码/调用的耗时, meter统计TPS。


public class TimerTest {

    public static Random random = new Random();

    public static void main(String[] args) throws InterruptedException {
        MetricRegistry registry = new MetricRegistry();
        ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build();
        reporter.start(1, TimeUnit.SECONDS);

        Timer timer = registry.timer(MetricRegistry.name(TimerTest.class,"get-latency"));

        Timer.Context ctx;

        while(true){
            ctx = timer.time();
            Thread.sleep(random.nextInt(1000));
            ctx.stop();
        }

    }

}
  

运行之后结果如下:


-- Timers ------------------------------------------------
com.alibaba.wuchong.metrics.TimerTest.get-latency
             count = 38
         mean rate = 1.90 calls/second
     1-minute rate = 1.66 calls/second
     5-minute rate = 1.61 calls/second
    15-minute rate = 1.60 calls/second
               min = 13.90 milliseconds
               max = 988.71 milliseconds
              mean = 519.21 milliseconds
            stddev = 286.23 milliseconds
            median = 553.84 milliseconds
              75% <= 763.64 milliseconds
              95% <= 943.27 milliseconds
              98% <= 988.71 milliseconds
              99% <= 988.71 milliseconds
            99.9% <= 988.71 milliseconds
  

其他

初次之外,Metrics还提供了 HealthCheck 用来检测某个某个系统是否健康,例如数据库连接是否正常。还有Metrics Annotation,可以很方便地实现统计某个方法,某个值的数据。感兴趣的可以点进链接看看。

使用经验总结

一般情况下,当我们需要统计某个函数被调用的频率(TPS),会使用Meters。当我们需要统计某个函数的执行耗时时,会使用Histograms。当我们既要统计TPS又要统计耗时时,我们会使用Timers。

转   自 http://wuchong.me/blog/2015/08/01/getting-started-with-metrics/


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MetricsSystem 的相关文章

  • CentOS中添加Swap

    1 检查 Swap 空间在设置 Swap 文件之前 xff0c 有必要先检查一下系统里有没有既存的 Swap 文件 运行以下命令 xff1a 1 swapon s 如果返回的信息概要是空的 xff0c 则表示 Swap 文件不存在 2 检查
  • 优秀程序员的故事

    A君默默的工作了3年 xff0c 从项目初立 xff0c 到遍地开花 工作不忙 xff0c 工资没长 新领导来了 xff0c 下个版本重新开发 xff0c A君继续维护老版本 新招了一批人 xff0c 加班加点干了半年多 直到版本发布 xf
  • android studio 控制台输出乱码

    问题 android studio 控制台输出乱码 详细问题 解决方案 双击Shift 全局查找快捷键 xff0c 输入vmoption xff0c 选择Edit Custom CM Options 即 如果之前没有配置过 xff0c 会弹
  • Linux下使用VSCode,GCC,OpenOCD实现STM32一键编译烧录调试(CMake篇)

    Linux下使用VSCode开发STM32 xff08 二 xff09 一 开发工具安装二 测试工程简介三 CMake工具1 CMakeLists txt2 生成Makefile3 make编译 四 json脚本实现一键编译烧录调试1 la
  • CMake Error at cmake/OpenCVDetectCXXCompiler.cmake:85 (list)

    Ubuntu 18 4 安装opencv 2 4 10时遇到如下问题 xff1a CMake Error at cmake OpenCVDetectCXXCompiler cmake 85 list list GET given empty
  • Camera-IMU标定工具Kalibr的编译

    关于catkin make过程中下载suitesparse过久甚至失败的问题 xff1a 在安装kalibr时的suitesprse库时 xff0c 对应的cmakelists中会通过wget 下载压缩包 xff0c 若无法下载则整个kal
  • 远程桌面,RDP文件密码加密、解密算法(C#)

    背景 xff1a 由于项目需要 xff0c 使用RDP文件来远程登录 xff0c 需要实现点击rdp文件就可以自动连接远程桌面 xff0c 并且实现自动登录功能 xff01 自动登录 xff01 自动登录 xff01 自动登录 xff1a
  • 解决apt install存在依赖关系导致无法安装成功的办法

    安装aptitude xff0c 使用aptitude进行安装会自动给出解决方案 sudo apt get install aptitude sudo aptitude install XXX
  • cubemx在使用freertos的时候为何推荐使用除systick以外的timebase

    摘要 第一次使用stm32cubemx 在配置freertos后生成代码时会提示 When FreeRTOS is used It is strongly recommended to use a HAL timebase source o
  • 状态机编程 (一) 状态机相关概念

    基本概念 状态机编程 xff0c 又称事件驱动型编程 事件驱动程序需要一系列的精细粒度的事件处理函数来处理事件 这些事件函数必须处理的很快并返回主事件循环 所以其非常依赖于通过使用静态变量维护在从一个事件驱动函数转换到下一个执行函数时的执行
  • 后端状态估计-卡尔曼滤波器理解+扩展-SLAM14讲笔记(六)

    文章目录 系列文章目录前言一 pandas是什么 xff1f 二 使用步骤 1 引入库2 读入数据 状态估计的概率解释 xff1a 位姿x和路标y服从某种概率分布 xff0c 目的是通过某些运动数据u xff08 比如惯性测量传感器IMU输
  • OpenCV笔记.1 - OpenCV的编译和安装

    OpenCV的编译和安装 想要使用OpenCV进行图像的处理和开发 xff0c 就需要先对OpenCV库进行编译 虽然在Windows下已经有了现成的OpenCV库 xff0c 但是由于官方提供的库缺少一些关键的功能 xff08 例如Ope
  • Git中stash和stage的差别

    对于初学者来说 xff0c git中stash和stage两个命令的单词有些相似 xff0c 有可能会弄混 其实二者是两个完全不同的概念 1 stash是git中的一个命令 git stash的作用是把工作区 必须是工作区中已经被git追踪
  • 用matlab和RTB做二连杆机械臂动力学建模

    文章目录 写在前面二连杆机械臂RTB建模仿真与验证源代码 写在前面 本文使用的工具为matlab以及Peter Corke的RTB Robotics Toolbox 基于RTB 10 3 1版本 xff0c 我写了RTE Robotics
  • 机械臂协同搬运中的阻抗控制

    文章目录 阻抗模型物体阻抗分布阻抗Matlab和RTB仿真物体阻抗分布阻抗 源代码 阻抗模型 阻抗控制的目的是将原有物体动力学修正为我们期望动力学 假设有一个弹簧 xff0c 通过阻抗控制 xff0c 可以使得它的刚度降低 xff0c 实际
  • MATLAB App Designer生成独立GUI(可执行exe)并添加依赖项

    文章目录 写在前面生成步骤设置编译器编写GUI生成exe 常踩的坑 写在前面 近期 xff0c 由于朋友需求以及科研任务要求 xff0c 我研究了一下MATLAB GUI设计 xff0c 写了两个小程序 一个是读取excel部门名单生成ex
  • 用MATLAB仿真仿射队形变换(affine formation maneuver)

    文章目录 写在前面如何仿真静态编队控制构建stress matrixMATLAB求解LMI问题静态编队控制源代码 如何仿真时变轨迹和队形变换轨迹生成时变leader控制律时变轨迹和队形变换源代码 写在前面 原论文标题 xff1a Affin
  • 多智能体一致性(Consensus)中的矩阵理论(Matrix Theory)

    文章目录 写在前面一致性算法连续时间离散时间 一致性证明连续时间离散时间 矩阵理论特征值和特征向量特征多项式代数重数几何重数 总结 写在前面 最近在看一些分布式优化的文章 xff0c 但是大部分文章都是用的离散时间算法 我之前一直研究的是连

随机推荐

  • 【论文笔记】利用平滑度加速分布式优化——梯度跟踪法(Gradient Tracking)

    文章目录 写在前面问题描述和算法收敛性证明 写在前面 原论文 xff1a Harnessing Smoothness to Accelerate Distributed Optimization 本文是Qu 20181的笔记 xff0c 主
  • 迭代器是什么,C++ STL迭代器(iterator)用法详解

    无论是序列容器还是关联容器 xff0c 最常做的操作无疑是遍历容器中存储的元素 xff0c 而实现此操作 xff0c 多数情况会选用 迭代器 xff08 iterator xff09 来实现 那么 xff0c 迭代器到底是什么呢 xff1f
  • C++ priority_queue 用法详解

    不出所料 xff0c priority queue 容器适配器定义了一个元素有序排列的队列 默认队列头部的元素优先级最高 因为它是一个队列 xff0c 所以只能访问第一个元素 xff0c 这也意味着优先级最高的元素总是第一个被处理 但是如何
  • 数据库|SQLite编程实例---在线词典

    在线词典项目实例 1 在线词典功能分析 在线词典功能分析框图 2 服务器端和客户端流程图 服务器端流程示意图 客户端流程示意图 3 服务器端和客户端源码 服务器端源码 span class token comment dict server
  • 【力扣刷题】动态规划问题的思考与总结

    文章目录 什么是动态规划解决动态规划问题的步骤基础递推算法子问题求和爬楼梯杨辉三角 子问题最值最大子序和 二维DP数组非最优子结构 买卖股票 xff08 多状态递推 xff09 打家劫舍 xff08 分治算法 xff09 贪心算法背包问题
  • 百度2014移动研发笔试题目

    答案仅供参考 一 简答题 1 简述计算机的存储系统分为哪几个层次 xff0c 为什么这样的分层能够提高程序的执行效率 所谓存储系统的层次结构 xff0c 就是把各种不同存储容量 存取速度和价格的存储器按层次结构组成多层存储器 xff0c 并
  • 横屏layout-land失效的细节问题 以及谈谈不同设置模式的优缺点

    android configChanges 61 34 orientation keyboardHidden screenSize 34 设置之后手机可以识别横屏布局 xff0c 但是不会重建 xff0c 但是pad不识别 xff0c 头疼
  • 数学公式汇总

    高等数学公式篇 平方关系 xff1a sin 2 43 cos 2 61 1 tan 2 43 1 61 sec 2 cot 2 43 1 61 csc 2 积的关系 xff1a sin 61 tan cos cos 61 cot sin
  • KEIL ARM 6.12 compiler 编译__ASM 错误的解决方法

    1 问题 KEIL compiler 设置为 use default compiler version 5 可以正确编译以下汇编和C混合代码 xff0c 更改编译器为V6 12后不识别 ASM关键字 xff0c 并对汇编语法报错 替换为 A
  • 面试题:从给定的N个正数中选取若干个数之和最接近M

    这道题跟捞鱼问题一样 xff0c 都是刚进实验室新生培训那会儿做过的题目 xff0c 不过这个是一师姐当时找工作的面试题 如题 xff0c 并输出该子序列 测试用例 xff1a 2 xff0c 9 xff0c 5 xff0c 7 xff0c
  • 贝叶斯最优分类器

    贝叶斯常常有两个问题 xff1a xff08 1 xff09 给定训练数据 xff0c 最可能的假设是什么 xff1f xff08 2 xff09 给定训练数据 xff0c 对新实例的最可能分类是什么 xff1f 第一个问题用最大后验概率
  • 奇异值分解SVD应用—LSI/LSA

    原文 xff1a http blog csdn net abcjennifer article details 8131087 xff08 有看不懂的地方 xff0c 原文评论有点解答 xff09 潜在语义索引 xff08 Latent S
  • EAGAIN、EWOULDBLOCK、EINTR与非阻塞 长连接

    EAGAIN EWOULDBLOCK EINTR与非阻塞 长连接 EWOULDBLOCK用于非阻塞模式 xff0c 不需要重新读或者写 EINTR指操作被中断唤醒 xff0c 需要重新读 写 在Linux环境下开发经常会碰到很多错误 设置e
  • WebSocket 实战

    本文介绍了 HTML5 WebSocket 的由来 xff0c 运作机制及客户端和服务端的 API 实现 xff0c 重点介绍服务端 xff08 基于 Tomcat7 xff09 及客户端 xff08 基于浏览器原生 HTML5 API x
  • FreeRTOS系列|FreeRTOS简介

    FreeRTOS简介 1 RTOS简介 RTOS全称为 Real Time Operation System xff0c 即实时操作系统 RTOS强调的是实时性 xff0c 又分为硬实时和软实时 硬实时要求在规定的时间内必须完成操作 xff
  • makefile 编写之32 or 64位机器

    一 Makefile 判断 64位机器 ARCH 61 shell uname m BIT32 61 i686 BIT64 61 x86 64 all clean ifeq ARCH BIT64 64 echo x86 64 make Su
  • linux多行注释

    1 多行注释 xff1a 1 首先按esc进入命令行模式下 xff0c 按下Ctrl 43 v xff0c 进入列 xff08 也叫区块 xff09 模式 2 在行首使用上下键选择需要注释的多行 3 按下键盘 xff08 大写 xff09
  • linux多线程信号处理

    在linux下 xff0c 每个进程都有自己的signal mask xff0c 这个信号掩码指定哪个信号被阻塞 xff0c 哪个不会被阻塞 xff0c 通常用调用sigmask来处理 同时每个进程还有自己的signal action xf
  • Mysql的row_format

    问题描述 xff1a You have an error in your SQL syntax check the manual that corresponds to your MySQL server version for the r
  • MetricsSystem

    Metrics xff0c 我们听到的太多了 xff0c 熟悉大数据系统的不可能没听说过metrics xff0c 当我们需要为某个系统某个服务做监控 做统计 xff0c 就需要用到Metrics 举个例子 xff0c 一个图片压缩服务 x