Grafana + Prometheus(面向 Java 开发者
2025-09-06 本文已影响0人
_浅墨_
Prometheus 负责「抓取 + 存时序指标 + 简易告警规则评估(Alerting)」;
Grafana 负责「可视化 + 告警路由/通知展示/仪表盘」。
Java 程序通过 Micrometer 等库把 JVM / 业务指标暴露为 Prometheus 能抓取的格式(/actuator/prometheus),Prometheus 抓取后用 PromQL 做告警与分析,Grafana 把这些 Query 做成漂亮的监控面板与告警面板。
核心组件职责(一句话)
- Prometheus:时序数据库 + 抓取器 + 查询(PromQL) + 基本告警评估。
- Grafana:可视化查询与仪表盘、告警规则管理(Grafana Alerting)以及多数据源支持(Prometheus、Loki、Tempo 等)。
- Java 端(Micrometer / Actuator):把应用内部(JVM/线程池/HTTP 请求/业务计数器)以 Prometheus 格式暴露出来。
何时选它们(使用场景)
- SRE/运维监控:系统级(node-exporter、kube-state-metrics)+ 应用级(JVM、请求延迟、错误率)。
- 性能回归与容量规划:历史时序数据、95/99 分位延迟趋势、资源使用率。
- SLO / SLA 监控:把业务请求成功率、延迟做为 SLI,用 Prometheus 计算并报警。
- 线上故障排查:快速用 PromQL 筛出异常实例并在 Grafana 上展示趋势。
- 多租户、k8s 集群监控:Prometheus Operator + ServiceMonitor 与 Grafana 结合。
快速实战
A. 在 Spring Boot 中暴露指标(Micrometer + Prometheus)
Maven 依赖
<!-- Spring Boot Actuator + Micrometer 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>
application.properties / application.yml(暴露 prometheus endpoint)
management.endpoints.web.exposure.include=health,info,prometheus
management.endpoint.prometheus.enabled=true
management.server.port=8080
# 若使用 Spring Security,需要允许 /actuator/prometheus 访问或配置 bearer token
简单的业务计数器与延迟示例
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
private final Counter requests;
private final Timer latency;
private final MeterRegistry registry;
public DemoController(MeterRegistry registry) {
this.registry = registry;
this.requests = registry.counter("app_requests_total","app","demo");
this.latency = registry.timer("app_request_latency_seconds","app","demo");
}
@GetMapping("/hello")
public String hello() {
requests.increment();
Timer.Sample sample = Timer.start(registry);
try {
// 业务逻辑
return "ok";
} finally {
sample.stop(latency);
}
}
}
访问 http://your-app:8080/actuator/prometheus 会看到 Prometheus 格式的指标。
B. Prometheus 抓取配置(prometheus.yml 最小示例)
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'spring-apps'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['app1:8080', 'app2:8080']
在 Kubernetes 中通常用 kubernetes_sd_configs + relabel_configs 或 Prometheus Operator 的 ServiceMonitor 来自动发现。
K8s 下常见(简化)ServiceMonitor 示例(Prometheus Operator)
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: myapp-servicemonitor
labels:
release: prometheus
spec:
selector:
matchLabels:
app: myapp
namespaceSelector:
any: true
endpoints:
- port: http
path: /actuator/prometheus
interval: 15s
常用 PromQL(示例 + 说明)
以下例子假定 Micrometer 已产生默认名为
http_server_requests_seconds_bucket、http_server_requests_seconds_count、jvm_memory_used_bytes等指标。
- 95th 延迟(秒)(基于 histogram)
histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket{job="myapp"}[5m])) by (le))
- 错误率(5 分钟)(status 标签含 5xx)
sum(rate(http_server_requests_seconds_count{job="myapp", status=~"5.."}[5m]))
/
sum(rate(http_server_requests_seconds_count{job="myapp"}[5m]))
- Heap 使用率(百分比)
(jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"}) * 100
- 进程 CPU 使用率(近 1 分钟速率)(结合 node exporter)
100 * rate(process_cpu_seconds_total{job="myapp"}[1m]) / machine_cpu_cores
- 实例是否存活
up{job="myapp"} == 0
Grafana 仪表盘要点(实践)
- 常见面板:TPS(QPS)、平均/分位延迟、错误率、JVM Heap/Non-Heap、GC pause、线程数、CPU、网络/磁盘 IO、数据库连接池使用率。
-
面板技巧:
- Latency 面板用
histogram_quantile(0.5/0.9/0.95)划分;显示 p50/p95/p99。 - 用 变量(templating) 支持按
instance、pod、uri切换。 - 使用 Annotations 将部署事件、发布流水线与 Grafana 时间线对齐,便于回溯。
- Latency 面板用
- 告警:可以在 Grafana(新的 Alerting)上设置告警,也可以继续在 Prometheus/Alertmanager 上面做告警评估并路由。
告警规则示例(Prometheus rule files)
groups:
- name: java.rules
rules:
- alert: HighHeapUsage
expr: (jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"}) > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "Heap usage >80% on {{ $labels.instance }}"
description: "Heap usage has been >80% for 5 minutes. value={{ $value }}"
- alert: HighErrorRate
expr: (sum(rate(http_server_requests_seconds_count{job="myapp",status=~"5.."}[5m])) by (instance)
/ sum(rate(http_server_requests_seconds_count{job="myapp"}[5m])) by (instance)) > 0.05
for: 2m
labels:
severity: critical
annotations:
summary: "High error rate (>5%) on {{ $labels.instance }}"
Alertmanager(路由示例)
route:
receiver: 'team-email'
receivers:
- name: 'team-email'
email_configs:
- to: 'oncall@example.com'
from: 'prometheus@your.org'
smarthost: 'smtp.your.org:587'
auth_username: 'prometheus'
auth_identity: 'prometheus'
Kubernetes + 生产注意事项(快速清单)
- 使用 node-exporter、kube-state-metrics、cadvisor 为主机与 k8s 提供基础指标。
-
避免高基数(cardinality)标签:不要把
user_id、order_id这种高基数标签直接作为 label。 - 合理设定 scrape_interval:默认 15s;高频指标/短任务可以短一些,但会增加存储与 CPU。
- 使用 histograms 而非 summary(跨实例合并),便于在 Prometheus 中做聚合统计。
- 记录规则(recording rules):把复杂/耗时的 PromQL 计算做成 recording rule,减轻查询压力。
- 长期存储:Prometheus 本地存储一般适合数周到数月,长期保存用 Thanos/Cortex/Remote write。
- 安全:在公共网络上启用 TLS、basic auth 或 使用 k8s NetworkPolicy 控制访问,Grafana 启用 OAuth / LDAP / RBAC。
典型故障排查流程(案例:线上延迟飙升)
- 在 Grafana 查看
95th latency面板,确认发生时间窗口。 - 在同一窗口查
error rate、cpu usage、GC pause、thread count。 - 若 GC pause 增大:检查
jvm_gc_pause_seconds、heap usage;考虑回退部署或扩大 pod replicas。 - 若 CPU 飙升但请求数不变:检查外部依赖(DB、Redis)延迟、连接池耗尽(
hikaricp_connections_active)。 - 用
topk(10, increase(http_server_requests_seconds_count[5m]))找出最热 endpoint,定位代码。 - 最终在 Grafana 上标注(annotation)本次根因与处理步骤,便于事后复盘。
最佳实践(经验总结)
- 强制规范 metric 命名(
{app}_{metric}_{unit})和 label 集合。 - 用 histogram 来度量延迟并保留 bucket,以便精准计算分位数。
- 记录规则与预计算:对常用/昂贵的查询(例如 95p latency)做 recording rule。
- 控制标签基数:把高基数信息做成 trace/span 或日志,而不是 label。
- 监控覆盖面:基础设施 -> k8s -> 应用(JVM、线程池、DB 连接)-> 业务 KPIs。
- 演练告警:定期演练 on-call 流程,避免误报/漏报。