JVM 接入

最近更新时间:2025-02-28 15:51:43

我的收藏

操作场景

在使用 Java 作为开发语言时,需要监控 JVM 的性能。Prometheus 监控服务通过采集应用暴露出来的 JVM 监控数据,并提供了开箱即用的 Grafana 监控大盘。
本文介绍了通过 client_javajmx_exporter 两种方式输出 JVM 指标,用 Prometheus 监控服务监控其状态。
说明:
若已使用 Spring Boot 作为开发框架,请参见 Spring Boot 接入

前提条件

创建腾讯云容器服务 托管版集群
使用 容器镜像服务 管理应用镜像。

指标埋点

client_java

client_java 是 Prometheus 官方提供的采集 SDK,提供简洁的 API 自定义指标埋点,还有开箱即用的 JVM 指标,是开发者接入 Prometheus 监控服务的首选方式。

修改应用的依赖及配置

1. 修改 pom 依赖。在 pom.xml 文件中添加相关的 Maven 依赖项,1.x 版本做了重构和老版本已经不兼容,优先选择最新版本,示例如下:
<dependency> <groupId>io.prometheus</groupId> <artifactId>prometheus-metrics-core</artifactId> <version>1.3.3</version> </dependency> <dependency> <groupId>io.prometheus</groupId> <artifactId>prometheus-metrics-instrumentation-jvm</artifactId> <version>1.3.3</version> </dependency> <dependency> <groupId>io.prometheus</groupId> <artifactId>prometheus-metrics-exporter-httpserver</artifactId> <version>1.3.3</version> </dependency>
2. 修改代码。初始化并注册 Metrics,示例如下:
package org.example; import io.prometheus.metrics.core.metrics.Counter; import io.prometheus.metrics.exporter.httpserver.HTTPServer; import io.prometheus.metrics.instrumentation.jvm.JvmMetrics;
import java.io.IOException; public class Main { public static void main(String[] args) throws InterruptedException, IOException { JvmMetrics.builder().register(); // 初始化并注册 JVM 指标
// 初始化并注册业务自定义指标 Counter counter = Counter.builder() .name("my_count_total") .help("example counter") .labelNames("status") .register(); counter.labelValues("ok").inc(); counter.labelValues("ok").inc(); counter.labelValues("error").inc();
// 启动 metrics http server HTTPServer server = HTTPServer.builder() .port(9400) .buildAndStart(); System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics") Thread.currentThread().join(); } }
3. 本地验证。本地启动之后,可以通过 http://localhost:9400/metrics 访问到 Prometheus 协议的指标数据。
http://localhost:9400/metrics

将应用发布到腾讯云容器服务上

1. 本地配置 Docker 镜像环境。如果本地之前未配置过 Docker 镜像环境,可以参见容器镜像服务 Docker 镜像操作快速入门 进行配置。若已配置请执行下一步。
2. 打包及上传镜像。
2.1 在项目根目录下添加 Dockerfile,请根据实际项目进行修改。示例如下:
FROM openjdk:8-jdk
WORKDIR /java-demo
ADD target/java-demo-*.jar /java-demo/java-demo.jar
CMD ["java","-jar","java-demo.jar"]
2.2 打包镜像,在项目根目录下运行如下命令,需要替换对应的 [namespace]、[ImageName] 和 [镜像版本号]。
mvn clean package
docker build . -t ccr.ccs.tencentyun.com/[namespace]/[ImageName]:[镜像版本号]
docker push ccr.ccs.tencentyun.com/[namespace]/[ImageName]:[镜像版本号]

jmx_exporter

jmx_exporter 是 Prometheus 官方 exporter,把 JVM 原生 MBeans 数据转换为 Prometheus 格式的指标并通过 HTTP 服务暴露出来。jmx_exporter 以 Java Agent 无代码侵入方式运行,但是只能暴露已经注册到 MBeans 上的指标,无法做业务自定义埋点。对于绝大部分的开发者,client_java 是最常用的接入手段。

准备 jmx_exporter 资源

1. 下载 jar 包。在项目 发布页 下载最新版本的 Java Agent Jar 包,这里以1.0.1为例。
wget https://repo.maven.apache.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/1.0.1/jmx_prometheus_javaagent-1.0.1.jar
2. 准备配置文件。此处使用最少可用配置,各个配置项的详细说明请参见 文档
rules:
- pattern: ".*"
3. 本地验证。jmx_exporter 启动格式是 -javaagent:<jmx_exporter jar 路径>=< metric 暴露端口>:< jmx_exporter 配置文件路径>
java -javaagent:./jmx_prometheus_javaagent-1.0.1.jar=9400:./jmx.yml -jar demo.jar
4. 正常启动后,访问 http://localhost:9400/metrics 会返回 jvm 开头的指标。
http://localhost:9400/metrics

将应用发布到腾讯云容器服务上

1. 本地配置 Docker 镜像环境。如果本地之前未配置过 Docker 镜像环境,请参见容器镜像服务 Docker 镜像操作快速入门 进行配置。若已配置请执行下一步。
2. 打包及上传镜像。
2.1 在项目根目录下添加Dockerfile,请根据实际项目进行修改。示例如下:
FROM openjdk:8-jdk
WORKDIR /java-demo
# 添加下载的 jmx_exporter jar 包
ADD ./jmx_prometheus_javaagent-1.0.1.jar /java-demo/jmx_prometheus_javaagent-1.0.1.jar
# 添加准备的 jmx_exporter 配置文件
ADD ./jmx.yml /java-demo/jmx.yml
ADD ./target/application.jar /java-demo/java-demo.jar
# 通过 java agent 注入 jmx_exporter
CMD ["java", "-javaagent:/java-demo/jmx_prometheus_javaagent-1.0.1.jar=9400:/java-demo/jmx.yml", "-jar", "java-demo.jar"]
2.2 打包镜像,在项目根目录下运行如下命令,需要替换对应的 [namespace]、[ImageName] 和 [镜像版本号]。
docker build . -t ccr.ccs.tencentyun.com/[namespace]/[ImageName]:[镜像版本号]
docker push ccr.ccs.tencentyun.com/[namespace]/[ImageName]:[镜像版本号]

应用部署

1. 登录 容器服务控制台,在左侧菜单栏中集群页面,选择需要部署的容器集群。
2. 通过工作负载 > Deployment 进入 Deployment 管理页面,选择对应的命名空间进行部署服务,通过 YAML 来创建对应的 Deployment,YAML 配置如下。
说明:
如需通过控制台创建,请参见 Spring Boot 接入
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
k8s-app: java-demo
name: java-demo
namespace: java-demo
spec:
replicas: 1
selector:
matchLabels:
k8s-app: java-demo
template:
metadata:
labels:
k8s-app: java-demo
spec:
containers:
- image: ccr.ccs.tencentyun.com/prometheus-demo/java-demo
imagePullPolicy: Always
name: java-demo
ports:
- containerPort: 9400
name: metric-port

添加采集任务

2. 在左侧菜单栏中选择 Prometheus 监控,选择对应 Prometheus 实例进入管理页面。
3. 选择数据采集 > 集成容器服务,进入到容器服务集成管理页面。
4. 选择数据采集配置 > 新增自定义监控 > yaml 编辑 > PodMonitors 新增抓取任务,YAML 配置示例如下:
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: java-demo
namespace: java-demo
spec:
namespaceSelector:
matchNames:
- java-demo
podMetricsEndpoints:
- interval: 15s
path: /metrics
port: metric-port
relabelings:
- action: replace
sourceLabels:
- __meta_kubernetes_pod_label_k8s_app
targetLabel: application
selector:
matchLabels:
k8s-app: java-demo


查看监控

1. 进入对应 Prometheus 实例,在数据采集 > 集成中心中找到 JVM 监控,安装对应的 Grafana Dashboard 即可开启 JVM 监控大盘。
2. 打开 Prometheus 实例对应的 Grafana 地址,在 Dashboards 下查看应用相关的监控大屏。
应用 JVM:从应用角度出发,查看该应用下所有实例是否存在异常,当发现某个实例有异常时,可以下钻到对应的实例监控。



实例 JVM:单实例 JVM 详细的监控数据。