什么是java的运行时系统_Java 系统运行时性能和可用性监控

现在,我已经介绍了性能数据跟踪 API、它的底层数据类型和数据收集的模式。接下来,我将通过一些用例和示例来演示 API 的应用。

监控 JVM  从 JVM 开始实现性能监控是个明智的选择。首先,我将介绍所有 JVM 共同的性能指标,然后再介绍企业给应用程序中经常使用的一些 JVM 驻留组件。通常,Java 应用程序实例是受底层操作系统支持的进程,因此,JVM 监控的某些方面最好是从主机 OS 的视角来理解,这些内容将在第 3 部分中介绍。

在 Java Platform, Standard Edition 5 (Java SE) 发行之前,能够在运行时有效和可靠收集的内部及标准化 JVM 诊断信息非常有限。现在,java.lang.management 接口提供了一些有用的监控点,该接口是所有兼容 Java SE 5(和更新版本)的 JVM 版本的标准。这些 JVM 的某些实现提供了额外的属性指标,但是它们的访问模式却基本相同。我将重点介绍可以通过 JVM 的 MXBeans 访问的标准模式 — 部署在 VM 内部的 JMX MBeans 公开了一个管理和监控接口

ClassLoadingMXBean:监控类加载系统。

CompilationMXBean:监控编译系统。

GarbageCollectionMXBean:监控 JVM 的垃圾收集器。

MemoryMXBean:监控 JVM 的堆和非堆内存空间。

MemoryPoolMXBean:监控 JVM 分配的内存池。

RuntimeMXBean:监控运行时系统。该 MXBean 提供的有用监控指标很少,但它确实提供了 JVM 的输入参数和启动时间及运行时间,这两者在其他派生指标中都是很有用的。

ThreadMXBean:监控线程系统。  JMX 收集器的前提是它将获取一个 MBeanServerConnection 对象,该对象可以读取部署在 JVM 中的 MBeans 的属性,读取目标属性的值,并使用 ITracer API 跟踪它们。对于这种类型的收集,决定部署收集器的位置非常关键。可行的选择包括本地部署 和远程部署

在本地部署中,收集器和它的调用调度程序部署在目标 JVM 中。随后,JMX 收集器组件将使用 PlatformMBeanServer(可以通过 JVM 内部的 MBeanServerConnection 来连接它)访问 MXBeans。在远程部署中,收集器运行在一个单独的进程中,并使用某种形式的 JMX Remoting 来连接目标 JVM。这可能没有本地部署那么高效,但它不需要在目标系统中部署任何额外的组件。JMX Remoting 不在本文的讨论范围之内,但它的实现方法非常简单:部署一个 RMIConnectorServer 或在 JVM 中启用外部连接。  示例 JMX 收集器

本文的示例 JMX 收集器包含三个单独的方法,可用于获取 MBeanServerConnection。该收集器可以:

通过调用静态 java.lang.management.ManagementFactory.getPlatformMBeanServer() 方法,为本地 JVM 的平台 MBeanServer 获取一个 MBeanServerConnection。

通过调用静态 javax.management.MBeanServerFactory.findMBeanServer(String agentId) 方法,为部署在本地 JVM 平台中的备用 MBeanServer 获取一个 MBeanServerConnection。注意,一个 JVM 中可以存在多个 MBeanServer,并且,Java Platform, Enterprise Edition (Java EE) 服务器等较为复杂的系统几乎始终拥有特定于应用服务器的 MBeanServer,它是独立的且有别于平台 MBeanServer。

使用 javax.management.remote.JMXServiceURL 通过标准 RMI Remoting 获取一个远程 MBeanServerConnection。

清单 2 是摘录自 JMXCollector collect() 方法的代码段,它显示了 ThreadMXBean 中的收集和线程跟踪活动。

清单 2. 示例 JMX 收集器的 collect() 方法的部分代码,它使用 ThreadMXBean

on = objectNameCache.get(THREAD_MXBEAN_NAME);

tracer.traceDeltaSticky((Long)jmxServer.getAttribute(on,"TotalStartedThreadCount"),

hostName, "JMX", on.getKeyProperty("type"), "StartedThreadRate");

tracer.traceSticky((Integer)jmxServer.getAttribute(on, "ThreadCount"), hostName,

"JMX", on.getKeyProperty("type"), "CurrentThreadCount");

.

.

// Done

long elapsed = System.currentTimeMillis()-start;

tracer.trace(elapsed, hostName, "JMX", "JMX Collector",

"Collection", "Last Elapsed Time");

tracer.trace(new Date(), hostName, "JMX", "JMX Collector",

"Collection", "Last Collection");

log("Completed JMX Collection in ", elapsed, " ms.");

} catch (Exception e) {

log("Failed:" + e);

tracer.traceIncident(hostName, "JMX", "JMX Collector",

"Collection", "Collection Errors");

}

}

清单 2 中的代码将跟踪 TotalThreadsStarted 和 CurrentThreadCount 的值。由于它是轮询收集器,因此两个跟踪都使用粘附选项。但是,由于 TotalThreadsStarted 是一个不断增加的数值,因此最吸引人的地方不是绝对值,而是已创建线程的速率。这样,该跟踪程序将使用 DeltaSticky 选项。图 7 显示了此收集器创建的 APM 指标树:

图7. JMX收集器APM指标树

JMX 收集器的一些方面并未显示在清单 2 中,比如说调度注册,它将每隔 10 分钟为 collect() 方法创建一个定期回调。  在清单 2 中,不同跟踪程序类型和数据类型的实现方法将由数据源决定。例如:

TotalLoadedClasses 和 UnloadedClassCount 将作为粘附增量被跟踪,因为它们的值始终递增,而且增量在测定类加载活动方面比绝对值更加有用。

ThreadCount 变量可增加或减少,因此它将作为粘附类型被跟踪。

收集错误 将作为内部事件被跟踪,它将在收集遇到异常时递增。

为了追求效率,由于目标 MXBeans 的 JMX ObjectName 在目标 JVM 的生存期不会更改,因此收集器使用 ManagementFactory 常量名来缓存名称。  对于 MXBeans 的两种类型 — GarbageCollector 和 MemoryPool — 准确的 ObjectName 无法预先知晓,但是您可以提供一个通用的模式。在这些情况下,在初次执行收集时,您将对 MBeanServerConnection 发起一个查询,并请求与提供模式相匹配的所有 MBeans 的列表。为避免未来在目标 JVM 的生存期执行查询,返回的匹配 MBean ObjectName 将缓存在内存中。

在某些情况下,收集的目标 MBean 属性可能不是纯数值类型。MemoryMXBean 和 MemoryPoolMXBean 就是这种情况。对于这些情况,属性类型是可查询键和值的 CompositeData 对象。对于 java.lang.management JVM 管理接口,MXBean 标准采用了 JMX Open Types 模型,在该模型中,所有属性都是语言无关的类型,如 java.lang.Boolean 和 java.lang.Integer。或者,对于 javax.management.openmbean.CompositeType 等复杂类型,这些类型可以被分解为相同简单类型的键/值对。简单类型的完整列表枚举在静态 javax.management.openmbean.OpenType.ALLOWED_CLASSNAMES 字段中。该模型支持一个类型独立层,使 JMX 客户机不用依赖于非标准的类,并且还可以支持非 Java 客户机,因为底层类型相对比较简单。有关 JMX Open Types 的更多信息,对于目标 MBean 属性是非标准复杂类型的情况,您需要确保定义该类型的类在收集器的类路径中。并且,您必须实现一些自定义代码来呈现检索到的复杂对象中的有用数据。

如果获取了单个连接并为所有收集保留了该连接,则需要通过错误检测和修复来创建一个新连接,以防止该连接出现故障。某些收集 API 提供断开监控程序,可以提示收集器关闭、消除和创建新连接。如果收集器尝试连接到由于维护而停机或由于其他原因而无法访问的 PDS,则收集器应该以合适的频率轮询并重新连接。跟踪连接的运行时间还可用于在检测到关机时减少收集的频率。这可以减少已超负荷运行了一段时间的目标 JVM 的开销。

这些示例中未实现的两个额外技巧可以改进 JMX 收集器的效率,并减少它在目标 JVM 中运行所需的开销。第一个技巧适用于从一个 MBean 中查询多个属性的情况。借助 getAttributes(ObjectName name, String[] attributes),您可以在一个调用中请求多个属性,而不必使用 getAttribute(ObjectName name, String attribute) 一次请求一个属性。这种差异在本地收集中可以忽略,但是在远程收集中却可以显著减少资源的使用,因为它可以减少网络调用的数量。第二个技巧是使用监控收集模式代替轮询模式,从而进一步减少 JMX 公开内存池的轮询开销。MemoryPoolMXBean 支持建立一个使用率阀值,超过该阀值时将触发向监控程序发送一个通知,而监控程序将跟踪该值。当内存使用率增加时,使用率阀值可以相应地增加。这种方法是缺陷是,如果使用率阀值没有微小的增量,则一些粒度级的数据可能会丢失,并且阀值下方的内存使用率模式将变为不可见。

最后一个未实现的技巧是测定运行时间和垃圾收集总运行时间的范围,并实现一些简单的算法来计算垃圾收集器处于活动状态的时间在已运行时间中的百分比。这是一个有用的指标,因为一些垃圾收集器(当前)是大多数应用程序必须要面对的问题。由于某些收集(分别执行了一段时间)是期望执行的,因此运行垃圾收集占用的时间可以更加清楚地反映 JVM 的内存健康状况。根据经验(因应用程序而大不相同),占用任何 15 分钟时间段内的 10% 以上则表示存在潜在问题。

收集器的外部配置为便于演示收集流程,本文介绍的 JMX 收集器经过了适当简化,但它仅限于硬编码的收集方式。理想情况下,收集器将实现数据访问方式,而外部提供的配置将提供内容。这种设计使收集器更具实用性,且易于重用。对于最高级别的重用,外部配置的收集器应该支持这些配置点:

PDS 连接工厂指令,为收集器提供用于连接到 PDS 的接口,以及在连接时使用的配置。

执行收集的频率。

尝试重新连接的频率。

收集的目标 MBean,或通配符形式的对象名称。

对于各目标,跟踪复合名称或者应该跟踪的度量片段,以及应该跟踪的数据类型。

清单 3 演示了 JMX 收集器的外部配置:

清单3. JMX收集器的外部配置示例

collectors.jmx.RemoteRMIMBeanServerConnectionFactory

jmx.rmi.url=service:jmx:rmi://127.0.0.1/jndi/rmi://127.0.0.1:1090/jmxconnector

AppServer3.myco.org,JMX

10000

attributeName="ThreadCount" Category="Threading"

metricName="ThreadCount" type="SINT"/>

attributeName="TotalCompilationTime" Category="Compilation"

metricName="TotalCompilationTime" type="SDINT"/>

注意,TargetAttribute 元素包含一个名为 type 的属性,它表示智能类型跟踪程序的参数化变量。SINT 类型表示粘附 int,SDINT 类型表示增量粘附 int.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值