使用Prometheus和Grafana监控Spring Boot应用

在现代云原生应用中,指标数据是系统可观测性的命脉。它们能准确反映应用的健康状态是运行良好还是濒临崩溃。Spring Boot 结合 Prometheus 和 Grafana,构建了一套强大的指标采集、存储与可视化解决方案。

本文将指导您将Spring Boot应用打造成指标生成引擎,并构建令运维团队惊艳的监控仪表盘。

第一步:使用Micrometer和Prometheus导出指标

添加相关依赖

首先在项目中添加micrometer-registry-prometheus依赖。

该依赖使Spring Boot Actuator能够以Prometheus可抓取的格式暴露指标。

Maven:

<dependency>  
    <groupId>io.micrometer</groupId>  
    <artifactId>micrometer-registry-prometheus</artifactId>  
</dependency>

Gradle:

implementation 'io.micrometer:micrometer-registry-prometheus'

暴露Prometheus端点

application.properties中启用端点:

management.endpoints.web.exposure.include=prometheus,health,info  
management.metrics.tags.application=my-spring-app

• /actuator/prometheus 端点现在以 Prometheus 格式提供指标数据。

• management.metrics.tags.application 为所有指标添加自定义标签(在多服务架构中很有用)。

验证端点

curl http://localhost:8080/actuator/prometheus

您将看到原始指标数据,如 jvm_memory_used_bytes(JVM内存使用字节数)和 http_server_requests_seconds_count(HTTP请求计数)。

第二步:配置Prometheus抓取指标

创建一个prometheus.yml配置文件来配置抓取您的Spring Boot应用指标:

global:  
  scrape_interval: 15s  
scrape_configs:  
  - job_name: 'spring-boot'  
    metrics_path: '/actuator/prometheus'  
    static_configs:  
      - targets: ['host.docker.internal:8080']  # Use 'localhost' if not using Docker  
    metrics_path: /actuator/prometheus

通过Docker运行Prometheus:

docker run -p 9090:9090 -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus

访问http://localhost:9090/targets确认运行成功。

第三步:构建Grafana仪表盘

使用Grafana连接Prometheus

安装运行Grafana:

docker run -d -p 3000:3000 grafana/grafana

访问 http://localhost:3000 登录Grafana (默认账密: admin/admin).

增加Prometheus数据源:

• URL地址:http://host.docker.internal:9090(Docker环境使用)或 http://localhost:9090(非Docker环境)

导入预置仪表盘

Grafana 社区为 Spring Boot 提供了丰富的仪表盘模板。以下是一些推荐:

JVM 指标:使用仪表盘 ID 4701

• 跟踪内存、线程、GC和CPU使用情况。

HTTP 指标:使用仪表盘 ID 6756

• 监控请求率、延迟和错误百分比。

导入方式

• 点击 “+” → “Import” → 输入仪表盘 ID。

第四步:创建自定义指标

让我们来跟踪一个业务相关的指标:登录尝试次数

使用MeterRegistry定义自定义指标

注入MeterRegistry并创建计数器:

@Component
public class LoginMetrics {
    private final Counter loginAttemptsCounter;
    private final Counter successLoginAttemptsCounter;
    private final Counter failureLoginAttemptsCounter;
    private final MeterRegistry meterRegistry;

    public LoginMetrics(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        this.loginAttemptsCounter = Counter.builder("login.attempts")
            .description("Total user login attempts")
            .tag("type", "auth")
            .register(meterRegistry);
        this.successLoginAttemptsCounter = Counter.builder("login.attempts")
            .description("Successful user login attempts")
            .tag("type", "auth")
            .tag("result", "success")
            .register(meterRegistry);
        this.failureLoginAttemptsCounter = Counter.builder("login.attempts")
            .description("Failed user login attempts")
            .tag("type", "auth")
            .tag("result", "failure")
            .register(meterRegistry);
    }

    public void incrementLoginAttempts(boolean success) {
        loginAttemptsCounter.increment();
        if (success) {
            successLoginAttemptsCounter.increment();
        } else {
            failureLoginAttemptsCounter.increment();
        }
    }
}

在服务中使用指标

@Service  
public class AuthService {  
    private final LoginMetrics loginMetrics;  
public AuthService(LoginMetrics loginMetrics) {  
        this.loginMetrics = loginMetrics;  
    }  
    public boolean login(String username, String password) {  
        boolean success = // ... authentication logic ...  
        loginMetrics.incrementLoginAttempts(success);  
        return success;  
    }  
}

这将生成三个时间序列:

• login_attempts_total{type="auth"} — 跟踪登录尝试总次数

• login_attempts_total{type="auth", result="success"} — 跟踪成功登录尝试次数

• login_attempts_total{type="auth", result="failure"} — 跟踪失败登录尝试次数

第五步:在Grafana中可视化自定义指标

创建跟踪登录尝试的仪表盘:

新增一个新的面板 → “Add panel”.

Query:

rate(login_attempts_total{application="my-spring-app"}[5m])
  • • 使用 rate() 函数计算5分钟内的每秒平均请求率

可视化配置

  • • 选择”Graph”图表类型以查看趋势。
  • • 将”result”标签分成独立的线条显示。

专业建议:添加统计面板展示总尝试次数:

sum(login_attempts_total) by (result)

生产环境最佳实践

1. 避免高基数:不要使用无界标签(如用户ID)

2. 使用层级化指标:按http.requests.total格式组织指标名称

3. 端点安全:使用Spring Security保护/actuator/prometheus端点

4. 设置告警:针对错误率激增或JVM内存溢出配置Grafana告警

小结

通过Prometheus和Grafana,您不仅是在监控应用——更是在深入理解系统运行。指标数据将转化为可读性极强的运维叙事,比如:

• “为什么昨天的登录尝试次数下降了?

• “新版本发布对GC暂停有什么影响?”

通过添加自定义指标,您可以将原始数据转化为可执行的洞察。现在就开始全面埋点监控——当你在深夜调试系统故障时,未来的你会感谢现在的决定!

请登录后发表评论

    没有回复内容