在这里插入图片描述

👋 大家好,欢迎来到我的技术博客!
📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。
🎯 本文将围绕Prometheus这个话题展开,希望能为你带来一些启发或实用的参考。
🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获!


Prometheus - 环境搭建实操:Linux 系统快速部署与基础配置

在当今云原生和微服务架构盛行的时代,可观测性(Observability)已成为保障系统稳定性和性能的关键支柱。而在这三大可观测性支柱——日志(Logging)、指标(Metrics)和追踪(Tracing)中,指标监控无疑是构建实时告警、容量规划和性能分析的基础。Prometheus 作为 CNCF(Cloud Native Computing Foundation)毕业的顶级项目,凭借其强大的多维数据模型、灵活的查询语言 PromQL、高效的本地存储以及活跃的社区生态,已成为现代监控体系的事实标准 📊。

本文将带你从零开始,在 Linux 系统上完成 Prometheus 的快速部署与基础配置,并通过一个真实的 Java 应用示例,展示如何将应用指标暴露给 Prometheus 并实现可视化监控。无论你是 DevOps 工程师、后端开发者还是 SRE,掌握 Prometheus 的部署与集成技能都将为你的技术栈增添重要一环 💪。

为什么选择 Prometheus?

在深入部署之前,让我们先理解 Prometheus 的核心优势:

  • 多维数据模型:所有数据都以时间序列形式存储,通过指标名称和键值对标签(labels)进行标识,支持强大的过滤和聚合。
  • PromQL 查询语言:一种功能强大且直观的查询语言,可对采集的数据进行实时计算、聚合和预测。
  • Pull 模型:Prometheus 主动从目标(Targets)拉取指标,简化了网络配置,天然支持服务发现。
  • 自治性:单节点设计,无需依赖分布式存储,每个服务器都是独立的,降低了运维复杂度。
  • 丰富的生态系统:拥有大量官方和社区维护的 Exporter,可轻松监控各种系统(如 Node Exporter 监控主机、Blackbox Exporter 监控网络等)和中间件(如 MySQL、Redis、Kafka)。

📌 小贴士:虽然 Pull 模型是主流,但 Prometheus 也通过 Pushgateway 支持 Push 模式,适用于批处理任务等短暂生命周期的场景。

环境准备

在开始部署前,请确保你有一台运行 Linux 操作系统的服务器。本文以 Ubuntu 22.04 LTS 为例,但操作步骤在 CentOS、Debian 等主流发行版上基本一致。你需要具备以下条件:

  • 一台具有公网 IP 或内网可访问的 Linux 服务器(建议 2 核 CPU、2GB 内存以上)
  • 具有 sudo 权限的用户账户
  • 基本的 Linux 命令行操作能力
  • 网络可访问外网(用于下载 Prometheus 二进制包)

首先,更新系统软件包索引:

sudo apt update && sudo apt upgrade -y

安装必要的工具,如 wgettar(通常已预装):

sudo apt install -y wget tar

下载并安装 Prometheus

Prometheus 官方提供预编译的二进制文件,我们可以直接从其官网下载最新稳定版本。截至本文撰写时,最新稳定版为 2.47.1,但请始终以 Prometheus 官方下载页面 为准。

步骤 1:创建专用用户和目录

出于安全考虑,我们不建议以 root 用户运行 Prometheus。创建一个专用的系统用户:

sudo useradd --no-create-home --shell /bin/false prometheus

创建存放 Prometheus 二进制文件和配置文件的目录:

sudo mkdir /etc/prometheus
sudo mkdir /var/lib/prometheus

设置目录所有权:

sudo chown prometheus:prometheus /etc/prometheus
sudo chown prometheus:prometheus /var/lib/prometheus

步骤 2:下载并解压 Prometheus

进入临时目录,下载 Prometheus 压缩包:

cd /tmp
wget https://github.com/prometheus/prometheus/releases/download/v2.47.1/prometheus-2.47.1.linux-amd64.tar.gz

解压并进入目录:

tar xvf prometheus-2.47.1.linux-amd64.tar.gz
cd prometheus-2.47.1.linux-amd64

将二进制文件复制到 /usr/local/bin(这是存放本地编译或手动安装程序的标准位置):

sudo cp prometheus /usr/local/bin/
sudo cp promtool /usr/local/bin/

设置正确的权限:

sudo chown prometheus:prometheus /usr/local/bin/prometheus
sudo chown prometheus:prometheus /usr/local/bin/promtool

将配置文件和示例文件复制到 /etc/prometheus

sudo cp -r consoles/ console_libraries/ /etc/prometheus
sudo chown -R prometheus:prometheus /etc/prometheus/consoles
sudo chown -R prometheus:prometheus /etc/prometheus/console_libraries

步骤 3:创建基础配置文件

Prometheus 的行为由 YAML 格式的配置文件控制。创建主配置文件 /etc/prometheus/prometheus.yml

sudo nano /etc/prometheus/prometheus.yml

填入以下最简配置:

# 全局配置
global:
  scrape_interval: 15s  # 默认抓取间隔
  evaluation_interval: 15s  # 规则评估间隔

# 告警规则文件(可选)
rule_files:
  # - "rules.yml"

# 抓取配置
scrape_configs:
  # 监控 Prometheus 自身
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

这个配置做了三件事:

  1. 设置全局抓取间隔为 15 秒(即每 15 秒从目标拉取一次指标)。
  2. 定义了一个名为 prometheus 的抓取任务(job),目标是 localhost:9090 —— 这正是 Prometheus 自身的 HTTP 接口地址。
  3. 注释掉了告警规则文件,后续可按需启用。

保存并退出编辑器,然后设置配置文件权限:

sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml

步骤 4:配置 systemd 服务

为了让 Prometheus 在系统启动时自动运行,并方便管理,我们将其注册为 systemd 服务。

创建服务文件:

sudo nano /etc/systemd/system/prometheus.service

填入以下内容:

[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target

[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
    --config.file=/etc/prometheus/prometheus.yml \
    --storage.tsdb.path=/var/lib/prometheus/ \
    --web.console.templates=/etc/prometheus/consoles \
    --web.console.libraries=/etc/prometheus/console_libraries \
    --web.listen-address=0.0.0.0:9090
Restart=always

[Install]
WantedBy=multi-user.target

关键参数说明:

  • --config.file:指定配置文件路径。
  • --storage.tsdb.path:指定时序数据库(TSDB)的存储路径。
  • --web.listen-address:监听所有网络接口的 9090 端口(默认只监听 localhost)。

重载 systemd 配置并启动服务:

sudo systemctl daemon-reload
sudo systemctl start prometheus
sudo systemctl enable prometheus  # 设置开机自启

检查服务状态:

sudo systemctl status prometheus

如果看到 active (running),说明 Prometheus 已成功启动 ✅。

步骤 5:验证部署

打开浏览器,访问 http://<你的服务器IP>:9090。你应该能看到 Prometheus 的 Web UI 界面。

在顶部导航栏点击 Status > Targets,你会看到一个名为 prometheus 的目标,状态为 UP,表示 Prometheus 已成功抓取自身指标。

你还可以在 Graph 页面输入 up 并执行查询。up 是一个内置指标,值为 1 表示目标健康,0 表示不健康。你应该会看到一条值为 1 的时间序列。

🔍 探索提示:尝试输入 prometheus_build_info,这会返回 Prometheus 的版本、构建信息等,是验证监控是否生效的好方法。

配置防火墙(可选但推荐)

如果你的服务器启用了防火墙(如 ufw),需要开放 9090 端口:

sudo ufw allow 9090/tcp
sudo ufw reload

监控你的第一个 Java 应用

Prometheus 的强大之处在于它能轻松集成各种应用。接下来,我们将创建一个简单的 Spring Boot 应用,并通过 Micrometer 库暴露指标给 Prometheus。

为什么选择 Micrometer?

Micrometer 是一个应用指标门面(Facade),类似于 SLF4J 之于日志。它提供了统一的 API,可以将指标发送到多种监控系统(包括 Prometheus、Datadog、InfluxDB 等)。Spring Boot 2.x 原生集成了 Micrometer,使得暴露 Prometheus 指标变得异常简单 🚀。

步骤 1:创建 Spring Boot 项目

你可以使用 Spring Initializr 快速生成项目。选择以下依赖:

  • Spring Web
  • Spring Boot Actuator
  • Micrometer Registry Prometheus

或者,如果你熟悉 Maven,pom.xml 应包含:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-registry-prometheus</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

步骤 2:配置 Actuator 端点

Spring Boot Actuator 提供了生产就绪的功能,如健康检查、指标暴露等。我们需要启用 Prometheus 指标端点。

application.yml 中添加:

management:
  endpoints:
    web:
      exposure:
        include: health,info,prometheus  # 暴露这些端点
  endpoint:
    health:
      show-details: always
  metrics:
    tags:
      application: ${spring.application.name}

这里的关键是 management.endpoints.web.exposure.include,它明确指定了要暴露的 Web 端点。prometheus 端点会以 Prometheus 文本格式返回所有指标。

步骤 3:编写一个简单的 REST 控制器

创建一个控制器,用于模拟业务逻辑:

// src/main/java/com/example/demo/DemoController.java
package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

    @GetMapping("/hello")
    public String hello(@RequestParam(defaultValue = "World") String name) {
        return "Hello, " + name + "!";
    }

    @GetMapping("/error")
    public String error() {
        throw new RuntimeException("Something went wrong!");
    }
}

步骤 4:自定义业务指标(可选)

除了自动收集的 JVM、HTTP 请求等指标,你可能还想跟踪特定业务逻辑。例如,统计某个操作的调用次数:

// src/main/java/com/example/demo/CustomMetricsService.java
package com.example.demo;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.stereotype.Service;

@Service
public class CustomMetricsService {

    private final Counter customCounter;

    public CustomMetricsService(MeterRegistry meterRegistry) {
        this.customCounter = Counter.builder("custom_business_operation_total")
                .description("Total number of custom business operations")
                .register(meterRegistry);
    }

    public void performOperation() {
        // 执行业务逻辑
        System.out.println("Performing a custom operation...");
        // 增加计数器
        customCounter.increment();
    }
}

然后在控制器中注入并使用:

@RestController
public class DemoController {

    private final CustomMetricsService customMetricsService;

    public DemoController(CustomMetricsService customMetricsService) {
        this.customMetricsService = customMetricsService;
    }

    @GetMapping("/custom")
    public String custom() {
        customMetricsService.performOperation();
        return "Custom operation performed!";
    }
}

步骤 5:运行 Java 应用

打包并运行应用(假设应用名为 demo):

./mvnw clean package
java -jar target/demo-0.0.1-SNAPSHOT.jar

默认情况下,Spring Boot 应用运行在 8080 端口。访问 http://localhost:8080/actuator/prometheus,你应该能看到类似如下的文本输出:

# HELP jvm_memory_used_bytes The amount of used memory
# TYPE jvm_memory_used_bytes gauge
jvm_memory_used_bytes{area="heap",id="G1 Eden Space",} 1.2345678E7
...
# HELP http_server_requests_seconds Timer of HTTP server requests
# TYPE http_server_requests_seconds summary
http_server_requests_seconds_count{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/hello",} 5.0
...
# HELP custom_business_operation_total Total number of custom business operations
# TYPE custom_business_operation_total counter
custom_business_operation_total 3.0

这就是 Prometheus 能理解的指标格式!🎉

步骤 6:配置 Prometheus 抓取 Java 应用

现在,我们需要告诉 Prometheus 去抓取这个 Java 应用的指标。编辑 Prometheus 配置文件:

sudo nano /etc/prometheus/prometheus.yml

scrape_configs 下添加一个新的 job:

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  # 监控 Java 应用
  - job_name: 'java-app'
    static_configs:
      - targets: ['localhost:8080']  # 假设 Java 应用和 Prometheus 在同一台机器

⚠️ 注意:如果 Java 应用部署在另一台服务器上,请将 localhost 替换为该服务器的 IP 地址。

重新加载 Prometheus 配置(无需重启服务):

sudo kill -HUP $(pgrep prometheus)

或者,更优雅的方式是使用 Prometheus 的热重载 API(需在启动时添加 --web.enable-lifecycle 参数,出于安全考虑默认禁用)。

回到 Prometheus Web UI,刷新 Status > Targets 页面。你应该能看到一个新的目标 java-app,状态为 UP

现在,你可以在 Graph 页面查询 Java 应用的指标了!例如:

  • http_server_requests_seconds_count:查看 HTTP 请求总数。
  • jvm_memory_used_bytes:查看 JVM 内存使用情况。
  • custom_business_operation_total:查看自定义业务操作计数。

深入理解 Prometheus 数据模型

为了更有效地使用 Prometheus,理解其核心数据模型至关重要。Prometheus 的所有数据都以**时间序列(Time Series)**的形式存储。

什么是时间序列?

一个时间序列由两部分组成:

  1. 指标名称(Metric Name):描述被测量的内容,如 http_requests_total
  2. 标签(Labels):键值对,用于区分同一指标的不同维度,如 method="POST", status="200"

例如,以下是一个完整的时间序列样本:

http_requests_total{method="POST", handler="/api/v1/create", status="201"} 42
  • 指标名称:http_requests_total
  • 标签:method="POST", handler="/api/v1/create", status="201"
  • 值:42
  • 时间戳:隐式存在(由 Prometheus 自动添加)

这种多维数据模型使得你可以轻松地进行切片(slicing)和切块(dicing)分析。例如,你可以查询:

  • 所有 POST 请求的总数:sum(http_requests_total{method="POST"})
  • 特定处理器的错误率:rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m])

常见指标类型

Prometheus 客户端库(如 Micrometer)通常支持以下四种指标类型:

  1. Counter(计数器):单调递增的数值,用于累计事件次数(如请求总数、错误数)。不能减少

    • 示例:http_requests_total
    • Java 代码:Counter counter = Counter.builder("my_counter").register(registry); counter.increment();
  2. Gauge(仪表盘):可任意增减的数值,用于表示瞬时值(如内存使用量、队列长度)。

    • 示例:jvm_memory_used_bytes
    • Java 代码:Gauge gauge = Gauge.builder("my_gauge", myObject, obj -> obj.getValue()).register(registry);
  3. Histogram(直方图):对观测值进行采样,并统计落入不同桶(buckets)的数量,同时记录总和与计数。常用于延迟、响应大小等。

    • 示例:http_request_duration_seconds_bucket
    • Java 代码:Timer timer = Timer.builder("my_timer").register(registry); timer.record(() -> doSomething());
  4. Summary(摘要):类似 Histogram,但直接在客户端计算分位数(如 P95, P99)。由于分位数无法在服务端聚合,通常推荐使用 Histogram

    • 示例:较少见,因聚合问题不常用。

下图展示了 Prometheus 指标类型及其用途的对比:

指标类型

Counter

Gauge

Histogram

Summary

单调递增
如:请求总数

可增可减
如:内存使用量

分桶统计+总和
支持服务端聚合

客户端计算分位数
不支持服务端聚合

配置告警规则

监控的价值不仅在于观察,更在于主动发现问题。Prometheus 通过 Alertmanager 组件实现告警管理,但告警规则本身是在 Prometheus 中定义的。

步骤 1:创建告警规则文件

/etc/prometheus/ 目录下创建 alert.rules.yml

sudo nano /etc/prometheus/alert.rules.yml

添加一个简单的规则:当 Java 应用实例宕机超过 1 分钟时触发告警。

groups:
- name: example
  rules:
  - alert: InstanceDown
    expr: up == 0
    for: 1m
    labels:
      severity: critical
    annotations:
      summary: "Instance {{ $labels.instance }} down"
      description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 1 minute."

规则说明:

  • expr:PromQL 表达式,up == 0 表示目标不可达。
  • for:持续满足条件的时间,避免瞬时抖动导致误报。
  • labels:附加到告警上的标签,可用于路由。
  • annotations:告警的详细信息,{{ $labels.xxx }} 是模板变量。

步骤 2:在主配置中引用规则文件

编辑 /etc/prometheus/prometheus.yml,取消注释并修改 rule_files

rule_files:
  - "alert.rules.yml"

重载配置:

sudo kill -HUP $(pgrep prometheus)

步骤 3:验证告警规则

在 Prometheus Web UI 中,点击 Alerts 菜单。你应该能看到 InstanceDown 规则,状态为 inactive(因为目标是 UP 的)。

为了测试,你可以临时停止 Java 应用:

# 假设 Java 应用 PID 为 12345
kill 12345

等待 1 分钟后刷新 Alerts 页面,状态应变为 pending,再过一会儿变为 firing

🛑 注意:这只是告警规则的定义。要真正收到通知(如邮件、Slack),你需要部署并配置 Alertmanager,这超出了本文范围,但可参考 Alertmanager 官方文档

可视化:Grafana 集成(简要介绍)

虽然 Prometheus 自带 Web UI,但 Grafana 提供了更强大、更美观的可视化能力。Grafana 原生支持 Prometheus 作为数据源。

快速集成步骤

  1. 安装 Grafana:参考 Grafana 官方安装指南
  2. 添加数据源:在 Grafana 中,进入 Configuration > Data Sources,选择 Prometheus,填入 Prometheus 的 URL(如 http://localhost:9090)。
  3. 导入仪表盘:Grafana 社区提供了大量现成的仪表盘模板。例如,搜索 JVM Micrometer Dashboard(ID: 4701),一键导入即可监控 Java 应用的 JVM、HTTP 请求等关键指标。

下图展示了典型的 Prometheus + Grafana + Java 应用监控架构:

渲染错误: Mermaid 渲染失败: Lexical error on line 3. Unrecognized text. .../actuator/prometheus] end subgr -----------------------^

最佳实践与常见问题

1. 配置管理

  • 版本控制:将 prometheus.yml 和告警规则文件纳入 Git 等版本控制系统。
  • 配置验证:使用 promtool check config /etc/prometheus/prometheus.yml 在部署前验证配置语法。

2. 性能与资源

  • 存储:Prometheus 的本地存储不适合长期保留(默认 15 天)。对于长期存储,可考虑 Thanos、Cortex 或远程写入(Remote Write)到兼容的 TSDB。
  • 抓取间隔:不要盲目设置过短的 scrape_interval,会增加目标和 Prometheus 的负载。15-60 秒通常是合理范围。

3. 安全

  • 网络隔离:Prometheus 的 Web UI 和 API 默认无认证。在生产环境中,应通过反向代理(如 Nginx)添加 Basic Auth 或集成 OAuth。
  • 最小权限:确保 Prometheus 运行用户只有必要权限。

4. 常见问题排查

  • Target Down:检查目标是否可达(telnet <ip> <port>),防火墙是否开放,应用是否暴露了 /metrics 端点。
  • No Data:在 Prometheus Graph 中查询 up,确认目标状态;检查应用日志是否有错误。
  • 高内存使用:可能是查询过于复杂或数据量过大。使用 tsdb analyze 工具分析存储。

结语

通过本文的实操,你应该已经成功在 Linux 系统上部署了 Prometheus,并将其与一个 Java 应用集成,实现了从指标暴露、抓取到查询的完整监控闭环。这仅仅是 Prometheus 强大功能的冰山一角 🌊。

Prometheus 的学习曲线可能稍显陡峭,但其带来的价值——实时洞察系统健康状况、快速定位性能瓶颈、预防故障发生——是无可估量的。随着你对 PromQL 的熟练和对指标模型的深入理解,你将能构建出更加精细、智能的监控体系。

下一步,你可以探索:

  • 使用 Service Discovery(如 Consul、Kubernetes)动态发现监控目标。
  • 部署 Alertmanager 实现多渠道告警通知。
  • 集成 Grafana 创建炫酷的业务监控大盘。
  • 学习 Recording Rules 预计算复杂查询,提升查询性能。

监控不是目的,而是手段。真正的目标是构建一个可靠、高效、可观察的系统,让用户满意,让开发者安心。愿你在可观测性的道路上越走越远!🚀

📚 延伸阅读


🙌 感谢你读到这里!
🔍 技术之路没有捷径,但每一次阅读、思考和实践,都在悄悄拉近你与目标的距离。
💡 如果本文对你有帮助,不妨 👍 点赞、📌 收藏、📤 分享 给更多需要的朋友!
💬 欢迎在评论区留下你的想法、疑问或建议,我会一一回复,我们一起交流、共同成长 🌿
🔔 关注我,不错过下一篇干货!我们下期再见!✨

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐