Java 类程序如何监控,核心不是先选采集器,而是先判断应用以什么方式暴露运行状态。常见路径有四类:
- Spring Boot Actuator:适合 Spring Boot 应用,开箱即用,通常配合 Micrometer 暴露 Prometheus 指标。
- Micrometer:适合非 Spring Boot 的自研 Java 应用,需要自己注册指标并暴露 HTTP 接口。
- JMX:适合 Kafka、Tomcat、Zookeeper 等 Java 中间件,也适合已经通过 MBean 暴露运行状态的程序。
- 组件自身指标接口:适合 Tomcat 这类本身就提供 HTTP 状态端点或专用监控接口的组件。
选型速查
| 场景 | 优先方式 | 原因 |
|---|---|---|
| Spring Boot 应用 | Actuator + Micrometer | 配置少,Prometheus 端点成熟 |
| 非 Spring Boot 自研 Java 应用 | Micrometer | 可在代码中定义业务指标和 JVM 指标导出方式 |
| Kafka、Zookeeper、Tomcat 等中间件 | JMX 或组件插件 | 很多 Java 中间件天然通过 JMX 暴露指标 |
| 组件已有 HTTP 指标/状态端点 | 组件自身接口 | 不必额外打开 JMX 或引入 javaagent |
使用 Actuator 监控 Spring Boot 应用
如果应用基于 Spring Boot,通常可以直接使用 Actuator 暴露指标。你可以用下面的提示词向 AI 追问具体配置:
如何开启 actuator,暴露 Prometheus 格式的监控指标?
下面是一个常见配置路径。不同 Spring Boot 版本的配置项可能略有差异,落地时应以项目依赖版本为准。
1. 引入依赖
在 pom.xml 中添加 Actuator 和 Prometheus registry:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
如果使用 Gradle:
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-registry-prometheus'
2. 配置 Actuator 端点
在 application.properties 中暴露 Prometheus 端点:
management.endpoints.web.exposure.include=*
management.endpoint.prometheus.enabled=true
management.metrics.export.prometheus.enabled=true
也可以使用 YAML:
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
prometheus:
enabled: true
metrics:
export:
prometheus:
enabled: true
生产环境通常不建议无差别暴露全部端点。如果只需要健康检查和 Prometheus 指标,可以将暴露范围收敛为:
management.endpoints.web.exposure.include=prometheus,health
3. 启动并验证指标端点
启动 Spring Boot 应用后,Actuator 的 Prometheus 端点通常暴露在:
http://localhost:8080/actuator/prometheus
用浏览器或 curl 访问该地址,如果能看到 Prometheus 文本格式指标,就可以使用 Prometheus 或 Categraf 抓取。
4. 扩展自定义指标
如果需要业务指标,可以在代码中注入 MeterRegistry 并注册自定义 Counter、Gauge、Timer 等指标。自定义指标应注意命名、标签数量和业务含义,避免把高基数字段直接作为标签。
使用 Micrometer 监控非 Spring Boot 应用
如果应用不是 Spring Boot,也可以直接使用 Micrometer 暴露 Prometheus 格式指标。Actuator 底层也是基于 Micrometer,但非 Spring Boot 应用需要自己完成 registry 创建和 HTTP 端点暴露。
可以继续用下面的提示词追问:
如果没有使用 actuator,仅仅使用了 micrometer,应该如何把指标导出到 Prometheus?
1. 添加 Micrometer 和 Prometheus 依赖
以 Maven 为例:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
2. 注册 PrometheusMeterRegistry
在应用代码中手动创建并注册 PrometheusMeterRegistry:
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.micrometer.prometheus.PrometheusConfig;
import io.micrometer.core.instrument.MeterRegistry;
PrometheusMeterRegistry prometheusRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
// 你可以通过 MeterRegistry 来注册自定义指标
// prometheusRegistry.counter("my_custom_counter").increment();
3. 暴露 Prometheus 指标 HTTP 接口
Micrometer 不会自动暴露 HTTP 接口,需要应用自己提供一个路径。例如在 Spring MVC 中:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PrometheusController {
private final PrometheusMeterRegistry prometheusRegistry;
public PrometheusController(PrometheusMeterRegistry prometheusRegistry) {
this.prometheusRegistry = prometheusRegistry;
}
@GetMapping("/prometheus")
public String scrape() {
return prometheusRegistry.scrape();
}
}
如果不是 Spring 项目,也可以用 Jetty、Undertow、Netty 等 WebServer 暴露 /prometheus 路径,并将 prometheusRegistry.scrape() 的内容作为响应。最后使用 Prometheus 或 Categraf 抓取该端点即可。
使用 JMX 监控 Java 中间件
如果要监控的不是自研 Java 程序,而是 Tomcat、Kafka、Zookeeper 等开源组件,通常可以通过 JMX 获取指标。可以使用下面的提示词向 AI 追问:
普通的 Java 中间件,比如 Tomcat、Kafka,应该如何采集其监控指标?
一种常见做法是使用 JMX Exporter:
- 下载 JMX Exporter jar 包。
- 准备对应组件的 JMX Exporter 配置文件。
- 在组件启动参数中添加 javaagent,例如:
-javaagent:/path/to/jmx_prometheus_javaagent-<version>.jar=PORT:/path/to/config.yaml
该参数会指定 JMX Exporter jar 路径、要暴露的指标端口以及配置文件路径。启动后,JMX Exporter 会在指定端口暴露 Prometheus 指标,例如:
http://localhost:PORT/metrics
不同组件需要不同配置文件。JMX Exporter 提供了多个示例,可参考:https://github.com/prometheus/jmx_exporter/tree/main/examples。
实际落地时,建议继续追问并理解这些问题:
config.yaml的配置项分别代表什么意思?- Java MBean 是什么?
- 如何配置 JMX Exporter 采集某个特定 MBean?
- 样例配置中的
rules、pattern、name、labels如何影响最终指标?
使用组件自身暴露的指标
有些组件自身就提供指标或状态接口。例如 Tomcat 可以通过 HTTP 端点 /manager/status/all 查看监控指标。Categraf 的 Tomcat 采集插件就是基于这个端点采集指标。
1. 配置访问用户
修改 tomcat-users.xml,增加访问 /manager/status/all 端点所需的用户:
<role rolename="admin-gui" />
<user username="tomcat" password="s3cret" roles="manager-gui" />
2. 调整访问限制
注释掉 webapps/manager/META-INF/context.xml 中的以下内容:
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
3. 配置 Categraf 采集
在 Categraf 的 conf/input.tomcat/tomcat.toml 中配置 Tomcat 采集地址和认证信息即可。
JMX 是相对通用的方式,但各组件自身暴露指标的方式并不统一。Tomcat 只是示例,其他组件需要分别查阅其文档和采集插件说明。
常见问题
Actuator、Micrometer 和 JMX 是互斥的吗?
不是。Actuator 适合 Spring Boot 应用,Micrometer 适合自研指标体系,JMX 适合 Java 运行时和中间件暴露指标。一个系统里可能同时存在多种方式,但采集侧要避免重复采集同一类指标。
为什么不建议所有指标都采集?
指标越多,采集、存储、查询和告警成本越高。尤其是带有高基数标签的指标,容易给时序数据库带来压力。更好的做法是先明确排障和容量分析需要哪些信号,再选择性采集。
Prometheus 和 Categraf 在这里分别做什么?
Actuator、Micrometer、JMX Exporter 或组件端点负责“暴露指标”;Prometheus、Categraf 或其他采集器负责“抓取指标并送到后端”。两者是暴露侧和采集侧的关系。
小结
Java 程序监控可以从应用框架、指标库、JMX 和组件自身接口四个入口切入。Spring Boot 应用优先考虑 Actuator;非 Spring Boot 自研应用可以直接使用 Micrometer;Java 中间件通常从 JMX 或组件专用采集插件入手。选型时先看程序如何暴露运行状态,再决定由 Prometheus、Categraf 或其他采集器来抓取。