Grafana + Prometheus(面向 Java 开发者)

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_buckethttp_server_requests_seconds_countjvm_memory_used_bytes 等指标。

  1. 95th 延迟(秒)(基于 histogram)
histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket{job="myapp"}[5m])) by (le))
  1. 错误率(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]))
  1. Heap 使用率(百分比)
(jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"}) * 100
  1. 进程 CPU 使用率(近 1 分钟速率)(结合 node exporter)
100 * rate(process_cpu_seconds_total{job="myapp"}[1m]) / machine_cpu_cores
  1. 实例是否存活
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) 支持按 instancepoduri 切换。
    • 使用 Annotations 将部署事件、发布流水线与 Grafana 时间线对齐,便于回溯。
  • 告警:可以在 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_idorder_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。

典型故障排查流程(案例:线上延迟飙升)

  1. 在 Grafana 查看 95th latency 面板,确认发生时间窗口。
  2. 在同一窗口查 error ratecpu usageGC pausethread count
  3. 若 GC pause 增大:检查 jvm_gc_pause_seconds、heap usage;考虑回退部署或扩大 pod replicas。
  4. 若 CPU 飙升但请求数不变:检查外部依赖(DB、Redis)延迟、连接池耗尽(hikaricp_connections_active)。
  5. topk(10, increase(http_server_requests_seconds_count[5m])) 找出最热 endpoint,定位代码。
  6. 最终在 Grafana 上标注(annotation)本次根因与处理步骤,便于事后复盘。

最佳实践(经验总结)

  • 强制规范 metric 命名({app}_{metric}_{unit})和 label 集合。
  • 用 histogram 来度量延迟并保留 bucket,以便精准计算分位数。
  • 记录规则与预计算:对常用/昂贵的查询(例如 95p latency)做 recording rule。
  • 控制标签基数:把高基数信息做成 trace/span 或日志,而不是 label。
  • 监控覆盖面:基础设施 -> k8s -> 应用(JVM、线程池、DB 连接)-> 业务 KPIs。
  • 演练告警:定期演练 on-call 流程,避免误报/漏报。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容