gpt4 book ai didi

java - 使用 Dropwizard 指标报告 JVM 的 CPU 使用率

转载 作者:搜寻专家 更新时间:2023-11-01 02:21:33 27 4
gpt4 key购买 nike

我使用 Dropwizard metrics衡量我的应用程序中的各种指标。它们是 JVM instrumentation 中的几个预定义记者,但奇怪的是我找不到任何报告 CPU 使用率的信息。

我可以创建自己的仪表(使用 getThreadCpuTime 或类似的),但我最好的猜测是我遗漏了一些东西。

我是否在当前实现中错过了它,或者它比我最初想象的更复杂?

最佳答案

我对 Dropwizard 了解不多,但我过去使用过 ThreadMXBean 来估计可扩展分布式计算系统中的 CPU 使用率,因此我将分享我认为与以下内容相关的内容这个问题。事情肯定比乍看起来要复杂:

ThreadMxBean 有点误导......

ThreadMxBean.getThreadCpuTime(id) 仅返回自线程启动以来特定线程在 CPU 上执行代码所花费的时间,以纳秒为单位。它没有提供有关您的线程可能已被阻塞或等待( hibernate )多长时间的信息,因此它确实无法让您很好地了解 CPU 使用情况。您还需要测量总阻塞/等待时间,然后在程序运行期间跟踪所有这三个值以跟踪 CPU 使用率。奇怪的是,ThreadMXBean 没有直接获取阻塞/等待时间的方法,因此您可能会想放弃。

...但您可以使用它来获取 ThreadInfo 对象...

首先,要启用它,请调用这两行(如果您的 JVM 不支持,这可能会抛出异常):

ManagementFactory.getThreadMXBean().setThreadCpuTimeEnabled(true);
ManagementFactory.getThreadMXBean().setThreadContentionMonitoringEnabled(true);

现在您可以调用ThreadMXBean.getThreadInfo(threadId) 来获取与特定线程对应的ThreadInfo 实例。此信息对象有两个方法,getBlockedTime()getWaitedTime(),它们返回您的线程在这两种状态中的任何一种状态下花费的总毫秒数。没有 getCpuTime() 方法(如果你问我,这是这个对象的一个​​非常愚蠢的缺点),但如果你知道你的线程何时启动,你可以这样做:

//Initialized somewhere else:
ThreadMXBean bean = ...
long threadStartTime = System.currentTimeMillis();
Thread myThread = ...

//Inside your metrics-gathering code:
long now = System.currentTimeMillis();
ThreadInfo info = bean.getThreadInfo(myThread.getId());
long totalCpuTime = now - (info.getBlockedTime()+info.getWaitedTime()+threadStartTime);

现在您可以计算线程利用率的百分比。

我们快完成了,但还没有完全完成。每次我们检查上面发布的代码的最后三行时,我们只收集线程执行/阻塞/等待状态的总时间。要计算百分比,我们需要跟踪收集这些指标的时间,以便我们可以知道自上次指标更新以来线程在每个状态中花费了多少时间。所以,做这样的事情:

class ThreadUsageMetrics{
long timestamp, totalBlockedTime, totalWaitTime;

ThreadUsageMetrics(long ts, long blocked, long wait){
timestamp = ts;
totalBlockedTime = blocked;
totalWaitTime = wait;
}

double computeCpuUsageSince(ThreadUsageMetrics prev){
long time = timestamp - prev.timestamp;
long blocked = totalBlockedTime - prev.totalBlockedTime;
long waited = totalWaitTime - prev.totalWaitTime;
return (time-(blocked+waited))/(double)time;
}
}

这将为我们提供 0.0 到 1.0 范围内的 double 值,表示自上次指标更新以来 CPU 使用率占总时间的百分比。我假设您可以将此值转换为百分比,并每隔 5 秒左右将其提供给 Dropwizard 的 Gauge 实例。在我的项目中,这就是我们多年来估算 CPU 使用率的方式,对我们来说效果很好。

关于此的几点说明 - 我们实际上不需要在此对象中显式存储总 CPU 时间,因为任何未花费在阻塞或等待上的时间要么是执行时间,要么是在上下文切换期间花费的时间。我们无法知道上下文切换时间,但可以安全地假设在所有情况下 99.9% 的总上下文切换时间可以忽略不计。

请注意 - 我们并未真正测量 CPU 使用率。

如果您仔细阅读,您会注意到我说过我们正在“估计”CPU 使用率。我这样说的原因是我们正在测量特定 Java Thread 的总执行时间。 Java 不提供实际 CPU 硬件使用的概念——它只是一个线程执行所花费的总时间。超线程之类的东西进一步混淆了这一点,其中“执行”所花费的时间实际上可能意味着等待其他线程离开 ALU 或内存总线所花费的时间。我认为这可以很好地衡量代码何时在物理硬件线程上运行,但如果您想衡量实际的 CPU 使用率,则无法在纯 Java 中完成。

关于java - 使用 Dropwizard 指标报告 JVM 的 CPU 使用率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40090757/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com