【Prometheus】一篇吃透|Docker部署Prometheus监控Java JVM完整实战(附全量代码+配置)
CSDN 可选标题(3组风格)
正文:一篇吃透 Docker+Prometheus 监控Java服务JVM(全实战代码)
一、前言 📢
微服务时代Java应用频繁出现OOM、GC卡顿、线程泄露、堆内存溢出等线上问题,JVM监控是定位性能故障的核心抓手。
Prometheus 搭配 Grafana 是当前云原生最主流的时序监控方案,本文全程基于 Docker / Docker Compose 容器化部署,覆盖:
- SpringBoot 接入Micrometer暴露JVM指标
- Docker打包Java应用,容器网络互通配置
- Prometheus容器抓取JVM指标完整yml配置
- Grafana可视化大盘导入+常用JVM PromQL
- JVM内存/GC告警规则编写
- 完整Mermaid架构流程图、可直接复制的源码配置
整体架构流程图(Mermaid)
流程简述:Java应用内置Micrometer暴露标准化Prometheus指标 → Prometheus定时拉取采集存储 → Grafana可视化JVM大盘 → 内存过高/频繁GC自动触发告警。
二、两种Java监控方案对比 🧐
方案1:SpringBoot Micrometer(推荐,本文重点)
适用:SpringBoot 2.x/3.x 微服务,零额外agent,原生集成,开箱自动导出完整JVM指标(堆、非堆、GC、线程、类加载、CPU)
方案2:JMX Exporter JavaAgent
适用:老旧非SpringBoot Java项目(Tomcat、普通Java Jar),通过javaagent挂载采集JMX数据
本文优先讲解Micrometer方案,文末补充JMX Exporter容器适配方式。
三、步骤1:SpringBoot项目集成Prometheus暴露JVM指标 📡
3.1 Maven pom.xml 引入依赖
在父 pom.xml 的 中声明的依赖
<!-- SpringBoot监控端点核心 -->
<!-- =================================================== -->
<!-- SpringBoot监控端点核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!-- Micrometer Prometheus注册表,自动生成JVM指标 -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.14.2</version>
</dependency>
<!-- =================================================== -->
在子模块 pom.xml 中应用
<!-- SpringBoot Actuator监控端点 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Micrometer Prometheus监控指标 -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
再在项目的拦截器放行路径,不校验登录
.........
// Prometheus监控指标端点,允许监控系统匿名访问
// 用于Prometheus Server定期拉取应用的监控指标数据,无需登录认证
.requestMatchers("/actuator/**").permitAll()
3.2 application.yml 监控配置(完整可复制)
spring:
application:
name: java-jvm-demo # 应用唯一标识,区分多服务监控指标
# Actuator监控端点配置
management:
endpoints:
web:
exposure:
# 开放健康检查、prometheus指标端点
include: health,prometheus,info,metrics
metrics:
export:
prometheus:
enabled: true
tags:
# 全局指标标签,多实例、多环境区分
env: dev
distribution:
percentiles-histogram:
http.server.requests: true # 开启接口响应分位数统计(95/99线)
endpoint:
health:
show-details: always # 展示完整健康详情
配置完成后,启动项目访问地址:http://127.0.0.1:8080/actuator/prometheus,页面会输出海量JVM原生指标,核心指标示例:
jvm_memory_used_bytes:堆/非堆内存占用jvm_gc_pause_seconds:GC停顿耗时jvm_threads_live:当前存活线程数jvm_classes_loaded_classes:加载类数量

3.3 自定义业务指标(扩展实战代码)
除原生JVM指标,可埋点业务计数器,监控接口调用量:
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class JvmDemoController {
// 注入指标注册器
@Resource
private MeterRegistry meterRegistry;
private final Counter apiVisitCounter;
// 初始化业务计数器
public JvmDemoController(MeterRegistry registry) {
this.apiVisitCounter = registry.counter("demo_api_visit_count", "api", "/hello");
}
@GetMapping("/hello")
public String hello() {
apiVisitCounter.increment(); // 每次访问计数器+1
return "JVM监控Demo服务运行正常";
}
}
3.4 Java应用Dockerfile打包(容器化部署)
# 基础JDK镜像
FROM openjdk:17-jdk-slim
WORKDIR /app
# 复制打包后的jar包
COPY target/jvm-monitor-demo-0.0.1-SNAPSHOT.jar app.jar
# JVM启动参数,优化监控日志
ENTRYPOINT ["java","-jar","app.jar"]
# 暴露服务端口
EXPOSE 8080
构建镜像命令:
docker build -t java-jvm-demo:1.0 .
# 启动Java容器,映射8080端口
docker run -d --name java-app -p 8080:8080 java-jvm-demo:1.0
四、步骤2:Docker Compose 部署Prometheus+Grafana监控栈 🐳
4.1 目录结构
monitor/
├── docker-compose.yml # 编排文件
├── prometheus/
│ └── prometheus.yml # Prometheus抓取配置(核心)
└── grafana-data/ # Grafana持久化数据(自动生成)
4.2 prometheus/prometheus.yml 配置(关键!抓取Java容器JVM指标)
重点:Docker容器互通,Linux宿主机网关
172.17.0.1;Windows/Mac Docker Desktop使用host.docker.internal
global:
scrape_interval: 10s # 每10秒采集一次指标
evaluation_interval: 10s # 告警规则检测间隔
# JVM监控抓取任务
scrape_configs:
- job_name: "jobName-java-jvm-monitor"
metrics_path: "/actuator/prometheus"
static_configs:
# 同一个docker网络就写服务名称,不同compose就写内网ip
- targets: ["zgb-admin:7777"]
labels:
service: labelsService-java-jvm-monitor
4.3 docker-compose.yml 完整编排文件
新的一个独立的配置
version: '3.8'
volumes:
prom_data: # Prometheus时序数据持久化
grafana_data: # Grafana面板配置持久化
services:
# Prometheus服务
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prom_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.retention.time=15d' # 数据保存15天
restart: unless-stopped
# Grafana可视化面板
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "4000:3000"
volumes:
- grafana_data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=123456
depends_on:
- prometheus
restart: unless-stopped
如果已经有docker-compose 就加入配置
version: '3.8'
services:
# ======================== MySQL 数据库 ========================
# mysql:
# image: mysql:8.0
# container_name: zgb-mysql
# restart: always
# environment:
# MYSQL_ROOT_PASSWORD: zgb@2026 # root 密码,部署时请修改
# MYSQL_DATABASE: zgb_sr # 自动创建的数据库
# TZ: Asia/Shanghai
# ports:
# - "3306:3306"
# volumes:
# - mysql-data:/var/lib/mysql # 数据持久化
# - ./sql:/docker-entrypoint-initdb.d # 首次启动自动执行 sql 目录下的初始化脚本
# command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
# networks:
# - zgb-net
# ======================== Redis 缓存 ========================
# redis:
# image: redis:7-alpine
# container_name: zgb-redis
# restart: always
# ports:
# - "6379:6379"
# command: redis-server --requirepass zgb@2026 # Redis 密码,部署时请修改
# volumes:
# - redis-data:/data
# networks:
# - zgb-net
# ======================== ZGB 应用服务 ========================
zgb-admin:
image: crpi-2toxc20jd1dwczcw.cn-shenzhen.personal.cr.aliyuncs.com/zhuguanbo/zgb-admin:1.0.0
container_name: zgb-admin
restart: always
ports:
- "7777:7777" # Spring Boot HTTP 端口
- "9999:9999" # Netty GPS 数据接收端口
environment:
TZ: Asia/Shanghai
JAVA_OPTS: "-Xms512m -Xmx512m -Djava.security.egd=file:/dev/./urandom"
# 激活生产环境配置
SPRING_PROFILES_ACTIVE: dev
volumes:
- app-logs:/app/logs # 日志持久化
- app-upload:/app/uploadPath # 上传文件持久化
networks:
- zgb-net
# ======================== Prometheus监控 ========================
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prom_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.retention.time=15d'
restart: unless-stopped
networks:
- zgb-net
# ======================== Grafana可视化面板 ========================
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "4000:3000"
volumes:
- grafana_data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=123456
depends_on:
- prometheus
restart: unless-stopped
networks:
- zgb-net
volumes:
# 原有业务持久卷
mysql-data:
redis-data:
app-logs:
app-upload:
# 新增监控持久卷
prom_data: # Prometheus时序数据持久化
grafana_data: # Grafana面板配置持久化
networks:
zgb-net:
driver: bridge
4.4 一键启动监控栈
# 进入monitor目录
cd monitor
# 后台启动所有容器
docker-compose up -d
# 查看容器运行状态
docker-compose ps
访问地址:
- Prometheus控制台:http://localhost:9090 → Status → Targets 查看Java服务是否UP
- Grafana面板:http://localhost:4000 账号admin/123456




五、步骤3:Grafana配置JVM可视化大盘 📊
-
Grafana添加数据源:Configuration → Data sources → Add data source 选择Prometheus,地址填写
http://prometheus:9090(容器互通域名),保存测试连通。


-
导入JVM标准大盘:Grafana官方SpringBoot JVM模板ID
4701,直接Import即可自动生成完整监控视图,包含:- 堆/非堆内存实时曲线
- 老年代/新生代GC频率、停顿时间
- 线程总数、阻塞线程、死锁线程
- 类加载数量、编译耗时
- HTTP接口QPS、99分位响应延迟

如果4701不存在,可以尝试
19004(SpringBoot3 专用,最新)
12900(通用 JVM Micrometer,替代 4701)
11946(极简 JVM 大盘,无依赖)


常用JVM核心PromQL查询语句(直接复制到Grafana)



下次进来在哪里能查看到这样页面?
- 堆内存使用率
(jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"}) * 100
- 5分钟GC平均次数
rate(jvm_gc_pause_seconds_count[5m])
- 活跃线程总数
jvm_threads_live_threads
- 接口99%响应耗时
histogram_quantile(0.99, sum(rate(http_server_requests_seconds_bucket[1m])) by (le,uri))
六、步骤4:JVM高内存/频繁GC告警规则配置 ⚠️
在prometheus.yml同级目录新建alert-rules.yml
groups:
- name: jvm-alert-rules
rules:
# 规则1:堆内存占用超过80%持续5分钟告警
- alert: JvmHeapMemoryHigh
expr: (jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"}) > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "Java应用堆内存占用过高"
description: "服务{{$labels.service}}堆内存使用率{{$value | humanizePercentage}},持续超过80%"
# 规则2:每分钟GC次数超过10次,频繁GC告警
- alert: JvmGcFrequent
expr: rate(jvm_gc_pause_seconds_count[1m]) > 10
for: 2m
labels:
severity: critical
annotations:
summary: "Java服务GC频繁,存在内存泄露风险"
修改prometheus.yml加载告警文件,在global下新增:
rule_files:
- "alert-rules.yml"

重启Prometheus容器生效:docker-compose restart prometheus
七、常见踩坑避坑指南 💡
- Prometheus Targets显示DOWN:
- 检查extra_hosts配置,Linux不能用host.docker.internal,替换172.17.0.1
- Java容器防火墙未开放8080端口,确认curl可访问
/actuator/prometheus
- JVM指标缺失:未开启
micrometer-registry-prometheus依赖,或端点未暴露prometheus - Grafana无数据:数据源地址写错,不能填localhost:9090,容器内使用prometheus服务名
- 内存告警不触发:scrape采集间隔过长,for持续时间未满足
九、总结 ✅
本文完整覆盖容器化Prometheus监控Java JVM全链路:
- SpringBoot Micrometer自动导出全套JVM指标,附带自定义业务埋点代码
- Docker Compose一键编排Prometheus+Grafana,全量可复制yml配置
- Mermaid架构流程图清晰梳理数据流
- 标准Grafana大盘导入、生产级JVM告警规则、通用PromQL
- 兼容老旧Java项目JMX Exporter方案与线上踩坑解决方案
整套方案零侵入、容器轻量化,直接落地生产环境,快速定位OOM、GC卡顿、线程泄露等JVM性能故障。
更多推荐
所有评论(0)