1. 项目概述从零构建一个现代监控告警系统最近在梳理团队的技术债务发现一个挺普遍的问题很多项目尤其是业务快速迭代期的产物监控和告警做得相当“随性”。要么是服务器挂了半天才有人发现要么是告警信息过于简陋半夜被吵醒却不知道问题出在哪排查起来像大海捞针。这让我想起了几年前自己从零搭建monitoring-alerting这套系统的经历。它不是什么高深莫测的黑科技而是一套基于开源生态、强调实用性和可维护性的解决方案核心目标就一个让系统状态透明化让问题发现自动化让故障定位精准化。简单来说这个项目就是一个集成了指标采集、可视化、告警规则管理和通知分发的完整栈。它非常适合中小型团队或初创公司在资源有限的情况下快速建立起符合 DevOps 理念的观测能力。你不需要成为 Prometheus 或 Alertmanager 的专家才能上手我会把当年踩过的坑、做的取舍以及最终沉淀下来的配置模板都揉碎了讲清楚。无论你是运维工程师、后端开发者还是对系统稳定性负责的 Tech Lead这套思路和实操细节都能直接拿来参考帮你把“救火”变成“防火”。2. 核心架构设计与技术选型背后的逻辑搭建监控告警系统第一步不是敲命令而是想清楚架构。市面上方案很多从商业 SaaS 到全家桶开源套件选择背后的逻辑决定了后续的维护成本和扩展性。2.1 为什么选择 Prometheus Grafana Alertmanager 黄金组合这几乎是现代云原生监控的事实标准。选型时我主要权衡了以下几点拉模型 vs 推模型Prometheus 基于拉模型Pull主动从目标抓取指标。这意味着你的应用只需要暴露一个标准的 HTTP 端点通常是/metricsPrometheus 服务器会定期来抓取。相比传统的推模型如 StatsD拉模型让监控服务器的运维更简单——你不需要在应用端配置监控服务器地址也更容易知道哪些目标正在被监控因为抓取目标列表在 Prometheus 配置中集中管理。当然对于短生命周期的任务如批处理作业我们也结合了 Pushgateway 作为补充。多维数据模型Prometheus 的指标通过键值对标签Label来标识一个指标名加上一组标签唯一确定一条时间序列。例如http_requests_total{methodPOST, handler/api/v1/users, status500}比传统的app.server.api.user.error.count灵活得多。你可以轻松地对任意标签维度进行聚合、筛选和告警比如“所有 handler 为/api/v1/*且状态码为 5xx 的请求速率”。强大的查询语言 PromQL这是 Prometheus 的灵魂。你可以用它进行实时查询、聚合、预测和计算。告警规则本质上就是基于 PromQL 的布尔表达式。一旦掌握排查问题的效率会极大提升。Alertmanager 的专业告警管理它不仅仅是发邮件。更重要的是处理告警的分组Grouping、抑制Inhibition、静默Silence和路由Routing。比如当一台宿主机宕机时其上的所有容器都会产生告警。Alertmanager 可以将这些告警分组为一条“宿主机XX故障”的通知避免告警风暴。你还可以根据告警标签如teambackend将告警路由到不同的接收器如 Slack 频道、钉钉群、PagerDuty。Grafana 的极致可视化它的图表丰富、仪表板配置灵活并且完美支持 Prometheus 数据源。更重要的是Grafana 的仪表板可以 JSON 文件化方便版本管理和团队共享。注意这套组合并非银弹。Prometheus 默认是单机、无集群方案的数据按时间分片存储于本地。对于超大规模千万级时间序列或长期历史数据存储超过数月需要考虑 Thanos 或 Cortex 等扩展方案。但对于绝大多数场景单机 Prometheus 配合合理的保留策略如 30-90天完全够用。2.2 整体数据流与组件职责理解了“为什么选”再看“怎么连”。整个系统的数据流非常清晰[你的应用/节点/中间件] --(暴露指标)-- [Prometheus Server] --(抓取存储)-- [时序数据库] ^ | | v [告警规则] --(评估PromQL)--- [Prometheus Server] --(触发告警)-- [Alertmanager] --(路由分发)-- [邮件/Slack/钉钉/Webhook] | ^ v | [Grafana] ------------------------------------------------------------(数据查询)数据采集层各类 Exporters如 node_exporter 用于主机监控mysqld_exporter 用于 MySQL和应用自身埋点通过 Prometheus Client Library提供指标端点。存储与计算层Prometheus Server 是核心负责定时抓取、存储指标数据并根据配置的rules.yml持续评估告警规则。告警处理层Alertmanager 接收来自 Prometheus 的告警进行去噪、分组、路由并调用对应的接收器发送通知。可视化层Grafana 查询 Prometheus 的数据生成可视化的仪表板。这个架构的松耦合性很好每个组件都可以独立部署、升级和扩展。3. 一步步搭建你的监控告警栈理论说再多不如动手搭一遍。下面我以在 Linux 服务器上部署为例演示核心组件的安装与基础配置。假设我们的工作目录是/opt/monitoring。3.1 第一步部署 Prometheus ServerPrometheus 是核心我们先把它跑起来。下载与解压cd /opt/monitoring wget https://github.com/prometheus/prometheus/releases/download/v2.45.0/prometheus-2.45.0.linux-amd64.tar.gz tar xvf prometheus-2.45.0.linux-amd64.tar.gz ln -s prometheus-2.45.0.linux-amd64 prometheus # 创建软链接方便管理编写核心配置文件prometheus.yml 这是 Prometheus 的“大脑”定义了抓取谁、怎么抓、抓什么。# /opt/monitoring/prometheus/prometheus.yml global: scrape_interval: 15s # 默认抓取间隔 evaluation_interval: 15s # 告警规则评估间隔 # 告警规则文件路径 rule_files: - rules/*.yml # 我们将告警规则放在单独的rules目录下 # 抓取配置列表 scrape_configs: # 第一个任务监控 Prometheus 自身 - job_name: prometheus static_configs: - targets: [localhost:9090] # Prometheus 默认暴露在9090端口 # 第二个任务监控所有 Linux 服务器节点 - job_name: node static_configs: - targets: [192.168.1.101:9100, 192.168.1.102:9100] # node_exporter 默认端口9100 # 可以添加公共标签这些标签会附加到该job下所有抓取到的指标上 labels: env: production role: app-server这个配置定义了两个抓取任务Job监控自己以及监控两台 IP 为192.168.1.101和102的服务器需要在这些服务器上安装node_exporter。创建 systemd 服务文件以 CentOS/RHEL 为例 为了让 Prometheus 在后台稳定运行并开机自启我们将其托管给 systemd。# /etc/systemd/system/prometheus.service [Unit] DescriptionPrometheus Server Afternetwork.target [Service] Userprometheus # 建议创建一个专门的用户 Groupprometheus Typesimple ExecStart/opt/monitoring/prometheus/prometheus \ --config.file/opt/monitoring/prometheus/prometheus.yml \ --storage.tsdb.path/data/prometheus \ # 数据存储目录确保有权限 --web.enable-lifecycle # 允许通过API热重载配置 Restarton-failure [Install] WantedBymulti-user.target创建用户和数据目录sudo useradd --no-create-home --shell /bin/false prometheus sudo mkdir -p /data/prometheus sudo chown -R prometheus:prometheus /data/prometheus /opt/monitoring/prometheus sudo systemctl daemon-reload sudo systemctl start prometheus sudo systemctl enable prometheus现在访问http://你的服务器IP:9090就能看到 Prometheus 的 Web UI 了。在 “Status - Targets” 页面可以看到我们配置的两个抓取目标的状态。3.2 第二步在目标服务器部署 Node ExporterNode Exporter 用于收集主机层面的指标CPU、内存、磁盘、网络等。在需要监控的每台 Linux 服务器上执行# 在目标服务器如192.168.1.101上操作 cd /tmp wget https://github.com/prometheus/node_exporter/releases/download/v1.6.0/node_exporter-1.6.0.linux-amd64.tar.gz tar xvf node_exporter-*.tar.gz sudo mv node_exporter-*/node_exporter /usr/local/bin/同样创建 systemd 服务# /etc/systemd/system/node_exporter.service [Unit] DescriptionNode Exporter Afternetwork.target [Service] Usernobody Groupnobody Typesimple ExecStart/usr/local/bin/node_exporter Restarton-failure [Install] WantedBymulti-user.targetsudo systemctl daemon-reload sudo systemctl start node_exporter sudo systemctl enable node_exporter此时访问http://192.168.1.101:9100/metrics应该能看到大量的指标文本。回到 Prometheus 的 Targets 页面node这个 job 下的目标状态应该会变成 “UP”。3.3 第三步部署与配置 Alertmanager告警逻辑由 Prometheus 触发但由 Alertmanager 处理。下载与解压cd /opt/monitoring wget https://github.com/prometheus/alertmanager/releases/download/v0.25.0/alertmanager-0.25.0.linux-amd64.tar.gz tar xvf alertmanager-*.tar.gz ln -s alertmanager-0.25.0.linux-amd64 alertmanager配置alertmanager.yml 这里配置告警如何路由和通知。以下是一个配置示例将告警发送到 Slack 和邮件。# /opt/monitoring/alertmanager/alertmanager.yml global: smtp_smarthost: smtp.gmail.com:587 # 邮件SMTP服务器 smtp_from: your-alert-emailgmail.com smtp_auth_username: your-alert-emailgmail.com smtp_auth_password: your-app-specific-password # 注意使用应用专用密码 slack_api_url: https://hooks.slack.com/services/XXXX/YYYY/ZZZZ # Slack Webhook URL route: group_by: [alertname, env] # 按告警名和环境分组 group_wait: 10s # 同一分组内等待10秒再发送为了聚合同时发生的告警 group_interval: 10s repeat_interval: 1h # 如果告警持续未解决每小时重复发送一次 receiver: default-receiver routes: # 子路由可以更精细地控制 - match: severity: critical receiver: critical-receiver continue: true # 继续匹配后续路由 receivers: - name: default-receiver email_configs: - to: teamyourcompany.com send_resolved: true # 告警恢复时也发送通知 slack_configs: - channel: #monitoring-alerts title: {{ .GroupLabels.alertname }} text: |- *状态*: {{ .Status | toUpper }} *环境*: {{ .GroupLabels.env }} *摘要*: {{ .CommonAnnotations.summary }} *详情*: {{ .CommonAnnotations.description }} *链接*: {{ .GeneratorURL }}|Prometheus - name: critical-receiver slack_configs: - channel: #oncall-critical title: [CRITICAL] {{ .GroupLabels.alertname }} text: 需要立即关注{{ .CommonAnnotations.description }} webhook_configs: # 还可以触发电话、短信等Webhook - url: http://your-pager-service/hook这个配置定义了两个接收器Receiver并根据告警的severity标签进行路由。所有告警都会发到default-receiver邮件和 Slack 常规频道而标记为critical的告警会额外发送到critical-receiverSlack 紧急频道和可能的电话 Webhook。创建 systemd 服务并启动步骤同 Prometheus略。在 Prometheus 中配置 Alertmanager 修改prometheus.yml告诉 Prometheus 将触发的告警发送到哪里。# 在 prometheus.yml 的 global 部分后添加 alerting: alertmanagers: - static_configs: - targets: - localhost:9093 # Alertmanager 默认端口3.4 第四步部署 Grafana 并配置数据源Grafana 是我们的展示窗口。安装以 CentOS 为例sudo yum install -y https://dl.grafana.com/oss/release/grafana-9.5.2-1.x86_64.rpm sudo systemctl start grafana-server sudo systemctl enable grafana-serverGrafana 默认运行在3000端口初始账号密码是admin/admin。添加 Prometheus 数据源 登录 Grafana 后点击左侧齿轮图标 “Configuration” - “Data sources” - “Add data source”选择 Prometheus。在 URL 栏填写http://localhost:9090如果 Grafana 和 Prometheus 在同一台机器然后点击 “Save test”应该显示 “Data source is working”。导入仪表板 从头创建仪表板费时费力社区有大量现成的优秀模板。例如要导入著名的 “Node Exporter Full” 仪表板ID: 1860在 Grafana 首页点击 “” - “Import”。在 “Import via grafana.com” 框内输入1860点击 Load。选择刚才添加的 Prometheus 数据源点击 Import。 瞬间一个功能齐全的主机监控仪表板就出现了包含了 CPU、内存、磁盘 IO、网络流量等所有关键图表。4. 编写有灵魂的告警规则告警规则是监控系统的“大脑”规则写得好告警才有效否则就是噪音制造机。告警规则文件如rules/node_alerts.yml由 Prometheus 加载并定期评估。4.1 告警规则的结构与最佳实践一条完整的告警规则包含以下部分groups: - name: node.rules # 规则组名 rules: - alert: InstanceDown # 告警名称全局唯一 expr: up{jobnode} 0 # PromQL 表达式结果为布尔值 for: 1m # 持续时长避免瞬时抖动 labels: severity: critical # 自定义标签用于告警路由和分类 team: infra annotations: summary: 实例 {{ $labels.instance }} 下线 description: {{ $labels.instance }} ({{ $labels.job }}) 已超过1分钟无法访问。 runbook: http://wiki.internal/runbooks/instance-down # 关联的应急预案链接最佳实践与心得for字段是你的朋友一定要用。网络瞬时抖动、进程短暂重启都可能触发up0设置for: 1m或for: 2m可以过滤掉这些噪音显著减少误报。善用labels进行路由severitycritical, warning、teambackend, frontend, dba、envprod, staging这些标签是 Alertmanager 路由规则的依据。务必在规则里打上清晰的标签。annotations要包含 actionable 信息summary和description要清晰指出哪里出了问题、可能的原因、以及下一步做什么。好的告警信息能让 on-call 工程师在睡眼惺忪时也能快速行动。附上runbook应急预案链接是专业体现。避免“狼来了”效应不要为每一个小波动都设置告警。关注影响业务的指标可用性up、错误率5xx、延迟p99、饱和度磁盘使用率、内存使用率。基于 SLO服务水平目标来设定告警阈值比拍脑袋定一个 80% 更有意义。4.2 经典告警规则示例解析下面分享几个经过实战检验的规则groups: - name: host.rules rules: # 规则1主机失联 - alert: HostOutage expr: up{jobnode} 0 for: 2m labels: severity: critical annotations: summary: 主机失联: {{ $labels.instance }} description: Prometheus 无法在2分钟内从 {{ $labels.instance }} 抓取指标。请检查主机状态、网络及 node_exporter 进程。 # 规则2高内存使用率关注可用内存而非已用内存百分比 - alert: HostMemoryRunningLow expr: (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 10 for: 5m labels: severity: warning annotations: summary: 主机内存不足: {{ $labels.instance }} (可用内存低于10%) description: 实例 {{ $labels.instance }} 的可用内存比例已持续5分钟低于10%。当前值{{ $value | humanizePercentage }}。可能影响应用性能。 # 规则3磁盘空间即将耗尽预测性告警 - alert: DiskWillFillIn4Hours expr: predict_linear(node_filesystem_free_bytes{jobnode, mountpoint!~.*pod.*}[1h], 4*3600) 0 for: 5m labels: severity: warning annotations: summary: 磁盘空间预计4小时内耗尽: {{ $labels.instance }} {{ $labels.mountpoint }} description: 根据过去1小时的趋势挂载点 {{ $labels.mountpoint }} 的剩余空间预计将在4小时内耗尽。请立即清理。 # 规则4应用业务指标告警假设应用暴露了 http_requests_total 指标 - alert: HighErrorRate expr: sum(rate(http_requests_total{status~5..}[5m])) by (service, endpoint) / sum(rate(http_requests_total[5m])) by (service, endpoint) 0.05 for: 2m labels: severity: critical team: backend annotations: summary: 高错误率: {{ $labels.service }} - {{ $labels.endpoint }} description: 服务 {{ $labels.service }} 的端点 {{ $labels.endpoint }} 在过去5分钟内错误率超过5%。当前值{{ $value | humanizePercentage }}。请检查应用日志和依赖服务。规则解析与踩坑点HostMemoryRunningLow使用MemAvailable而不是100 - (MemFree/MemTotal)*100。因为 Linux 会利用空闲内存做缓存Cached和缓冲Buffers这部分内存是可被应用程序快速回收的。MemAvailable是内核估算的真正可用内存更准确。DiskWillFillIn4Hours使用了predict_linear函数进行线性预测。[1h]表示基于过去1小时的数据预测4小时4*3600秒后的值。这是一个非常实用的预测性告警能在问题发生前给你预留处理时间。注意用mountpoint!~.*pod.*排除了 Kubernetes Pod 挂载的临时卷。HighErrorRate这是一个典型的业务层告警。它计算的是5xx错误请求占总请求的比例。rate()函数计算每秒速率[5m]是时间窗口。通过by (service, endpoint)按服务和端点维度聚合能精确定位到出问题的具体API。将写好的规则文件如node_alerts.yml放在 Prometheus 配置中rule_files指定的目录例如rules/下然后通过curl -X POST http://localhost:9090/-/reload热重载 Prometheus 配置或者重启 Prometheus 服务。5. 高级配置与生产级优化基础搭建完成后要让这套系统真正扛起生产环境的大旗还需要一些优化和高级特性。5.1 服务发现告别手动维护IP列表在动态的云环境或容器环境中服务器的 IP 是变化的。我们不可能每次扩缩容都去修改prometheus.yml。Prometheus 支持多种服务发现机制。基于文件的服务发现最简单的一种。Prometheus 读取一个 JSON 或 YAML 文件来获取目标列表。你可以写一个脚本定期从 CMDB 或云厂商 API 拉取服务器列表生成这个文件。# prometheus.yml scrape_configs: - job_name: node file_sd_configs: - files: - /etc/prometheus/targets/node*.json # 可以匹配多个文件 refresh_interval: 5m # 每5分钟重新读取文件# /etc/prometheus/targets/nodes.json [ { targets: [ 10.0.1.12:9100, 10.0.1.13:9100 ], labels: { env: production, region: us-east-1 } } ]基于 Kubernetes 的服务发现如果你用 K8sPrometheus 可以自动发现 Service、Pod、Endpoint 等资源并为其添加丰富的标签如 namespace, pod name, container name。这是监控容器环境的利器配置稍复杂需要赋予 Prometheus 相应的 RBAC 权限。5.2 告警模板让通知信息更友好Alertmanager 支持使用 Go template 来定制告警通知的格式。你可以创建一个模板文件让 Slack 或邮件的告警信息更加结构化、易读。# alertmanager.yml templates: - /etc/alertmanager/templates/*.tmpl # 指定模板文件路径# /etc/alertmanager/templates/custom.tmpl {{ define slack.custom.title }}[{{ .Status | toUpper }}] {{ .GroupLabels.alertname }} {{ .GroupLabels.env }}{{ end }} {{ define slack.custom.text }} *告警状态*: {{ .Status | toUpper }} *告警名称*: {{ .GroupLabels.alertname }} *故障实例*: {{ .CommonLabels.instance }} *触发时间*: {{ .StartsAt.Format 2006-01-02 15:04:05 UTC }} {{ range .Annotations }} *{{ .Name }}*: {{ .Value }} {{ end }} {{ range .Alerts }} *告警指纹*: {{ .Fingerprint }} {{ end }} *Grafana仪表板*: http://grafana.yourcompany.com/d/abc123|点击查看相关面板 *应急预案*: {{ .CommonAnnotations.runbook }}|Runbook {{ end }}然后在slack_configs中引用这个模板slack_configs: - channel: #alerts title: {{ template slack.custom.title . }} text: {{ template slack.custom.text . }}5.3 记录规则预计算以提升查询效率当你的 PromQL 查询非常复杂或需要频繁查询时可能会给 Prometheus 服务器造成压力。记录规则Recording Rule允许你预先计算好这些复杂的表达式并将其结果保存为一个新的时间序列。这样Grafana 仪表板或告警规则直接查询这个新的、简单的指标即可。定义在rules/目录下的record_rules.yml中groups: - name: recording_rules interval: 30s # 计算间隔可不同于抓取间隔 rules: - record: job:http_requests:rate5m # 新指标名推荐带冒号的命名空间 expr: sum(rate(http_requests_total[5m])) by (job) - record: instance:node_cpu_utilisation:rate5m expr: 1 - avg(rate(node_cpu_seconds_total{modeidle}[5m])) by (instance)之后告警规则中就可以直接使用job:http_requests:rate5m 100这样的简单表达式而不是冗长的sum(rate(...))。5.4 监控 Prometheus 自身与 Alertmanager监控系统自身也必须被监控。除了基础的up指标还要关注Prometheus:prometheus_tsdb_head_samples_appended_total样本摄入速率突然下降可能意味着抓取故障。prometheus_target_skipped_scrapes_total跳过的抓取次数过多可能配置有问题。process_resident_memory_bytes进程常驻内存持续增长可能内存泄漏。prometheus_rule_group_duration_seconds规则评估耗时耗时过长会影响告警及时性。Alertmanager:alertmanager_notifications_total和alertmanager_notifications_failed_total通知发送成功/失败计数。alertmanager_alerts当前活跃告警数。为它们也创建 Grafana 仪表板和关键的告警规则比如 Prometheus 抓取失败、自身内存过高。6. 实战问题排查与维护心得系统跑起来只是开始日常维护和问题排查才是重头戏。这里记录几个典型场景和我的处理思路。6.1 常见问题速查表问题现象可能原因排查步骤Prometheus Targets 显示DOWN1. 网络不通/防火墙2. Exporter 进程未运行3. 抓取配置错误端口、路径1.telnet target_ip port测试连通性。2. 登录目标机systemctl status node_exporter。3. 检查 Prometheus 配置的targets和 Exporter 实际端口。Grafana 图表显示 “No data”1. 数据源配置错误2. PromQL 查询语法错误3. 时间范围选择不当1. 在 Grafana 数据源配置页点击 “Save test”。2. 复制查询语句到 Prometheus 的 Graph 页面测试。3. 检查时间选择器是否跳到了未来或很久以前。收不到告警通知1. Alertmanager 未运行或配置未加载2. 告警规则未触发for时长不够3. 路由/接收器配置错误4. SMTP/Slack Webhook 配置错误1. 访问http://alertmanager:9093查看 UI 和状态。2. 在 Prometheus 的 “Alerts” 标签页查看告警状态是否为 “Firing”。3. 在 Alertmanager 的 “Status” 页面检查配置。4. 查看 Alertmanager 日志journalctl -u alertmanager -f。告警信息不准确1. 告警规则表达式逻辑错误2. 指标标签不一致或缺失1. 在 Prometheus 的 Graph 页面手动执行告警表达式验证结果。2. 使用up{jobnode}或{__name__~.*}查看目标暴露的原始指标和标签。Prometheus 内存/磁盘占用高1. 抓取目标过多/指标基数Cardinality爆炸2. 数据保留时间过长3. 记录规则或告警规则过于复杂1. 使用prometheus_tsdb_head_series查看时间序列总数。检查是否有标签值过多如将用户ID作为标签。2. 调整--storage.tsdb.retention.time参数。3. 优化记录规则合并相似查询。6.2 性能调优与容量规划心得控制指标基数这是影响 Prometheus 性能的最关键因素。指标基数是指唯一时间序列的数量。避免将高基数的维度如用户ID、请求ID、SessionID作为标签。每增加一个标签值就会产生一条新的时间序列。如果必须记录考虑将其作为日志输出或使用其他更适合高基数数据的系统如 Elasticsearch/Loki。合理的抓取间隔不是越短越好。scrape_interval: 15s是平衡实时性和负载的常用值。对于变化不频繁的指标如磁盘容量可以设置为30s或60s。在scrape_configs的 job 或 target 级别可以覆盖全局设置。规划存储Prometheus 本地存储的默认路径是--storage.tsdb.path。确保该目录所在磁盘有足够空间和 IOPS。一个粗略的估算公式所需磁盘空间 抓取间隔时间 × 指标数量 × 保留天数 × 每个样本约1-2字节。实际上配合压缩通常每百万时间序列每小时约需要 1-2GB。使用远程读写对于长期存储或跨 Prometheus 实例聚合查询可以配置remote_write将数据发送到 VictoriaMetrics、Thanos Receiver 或商业 TSDB。配置remote_read可以从这些远程存储查询数据。这能有效减轻本地 Prometheus 的压力。6.3 告警疲劳应对策略告警太多等于没有告警。如何减少噪音分级与路由充分利用 Alertmanager 的routes和labels。将告警分为critical需要立即行动、warning需要关注但非紧急、info仅记录。critical发短信/电话warning发 Slack/邮件info可能只记录不通知。维护期与静默对于计划内的维护如系统升级提前在 Alertmanager 的 Web UI (http://alertmanager:9093) 上创建静默规则Silence指定匹配的标签如instance~host-.*和时间范围避免收到无关告警。依赖抑制在alertmanager.yml中配置inhibit_rules。例如当“宿主机宕机”告警触发时抑制所有来自该宿主机上容器的“容器无响应”告警。inhibit_rules: - source_match: alertname: HostOutage target_match: alertname: ContainerDown equal: [instance] # 当instance标签相同时抑制目标告警定期评审与优化每季度或每半年团队一起 Review 一次告警规则。哪些告警从未触发哪些频繁触发但从未导致故障哪些告警触发了但信息无用根据 Review 结果优化或删除规则。这是保持告警系统健康度的必要仪式。搭建和维护一套监控告警系统是一个持续迭代的过程。它始于技术选型与部署但最终的价值体现在能否真正赋能团队快速发现、定位并解决线上问题从而提升系统的整体稳定性和团队的研发效率。这套基于 Prometheus 的栈以其灵活性和强大的社区生态为我们提供了一个坚实的起点。剩下的就是在实践中不断打磨规则、优化视图让它越来越贴合你的业务脉搏。
从零搭建基于Prometheus的监控告警系统:架构、部署与生产实践
发布时间:2026/5/17 1:21:36
1. 项目概述从零构建一个现代监控告警系统最近在梳理团队的技术债务发现一个挺普遍的问题很多项目尤其是业务快速迭代期的产物监控和告警做得相当“随性”。要么是服务器挂了半天才有人发现要么是告警信息过于简陋半夜被吵醒却不知道问题出在哪排查起来像大海捞针。这让我想起了几年前自己从零搭建monitoring-alerting这套系统的经历。它不是什么高深莫测的黑科技而是一套基于开源生态、强调实用性和可维护性的解决方案核心目标就一个让系统状态透明化让问题发现自动化让故障定位精准化。简单来说这个项目就是一个集成了指标采集、可视化、告警规则管理和通知分发的完整栈。它非常适合中小型团队或初创公司在资源有限的情况下快速建立起符合 DevOps 理念的观测能力。你不需要成为 Prometheus 或 Alertmanager 的专家才能上手我会把当年踩过的坑、做的取舍以及最终沉淀下来的配置模板都揉碎了讲清楚。无论你是运维工程师、后端开发者还是对系统稳定性负责的 Tech Lead这套思路和实操细节都能直接拿来参考帮你把“救火”变成“防火”。2. 核心架构设计与技术选型背后的逻辑搭建监控告警系统第一步不是敲命令而是想清楚架构。市面上方案很多从商业 SaaS 到全家桶开源套件选择背后的逻辑决定了后续的维护成本和扩展性。2.1 为什么选择 Prometheus Grafana Alertmanager 黄金组合这几乎是现代云原生监控的事实标准。选型时我主要权衡了以下几点拉模型 vs 推模型Prometheus 基于拉模型Pull主动从目标抓取指标。这意味着你的应用只需要暴露一个标准的 HTTP 端点通常是/metricsPrometheus 服务器会定期来抓取。相比传统的推模型如 StatsD拉模型让监控服务器的运维更简单——你不需要在应用端配置监控服务器地址也更容易知道哪些目标正在被监控因为抓取目标列表在 Prometheus 配置中集中管理。当然对于短生命周期的任务如批处理作业我们也结合了 Pushgateway 作为补充。多维数据模型Prometheus 的指标通过键值对标签Label来标识一个指标名加上一组标签唯一确定一条时间序列。例如http_requests_total{methodPOST, handler/api/v1/users, status500}比传统的app.server.api.user.error.count灵活得多。你可以轻松地对任意标签维度进行聚合、筛选和告警比如“所有 handler 为/api/v1/*且状态码为 5xx 的请求速率”。强大的查询语言 PromQL这是 Prometheus 的灵魂。你可以用它进行实时查询、聚合、预测和计算。告警规则本质上就是基于 PromQL 的布尔表达式。一旦掌握排查问题的效率会极大提升。Alertmanager 的专业告警管理它不仅仅是发邮件。更重要的是处理告警的分组Grouping、抑制Inhibition、静默Silence和路由Routing。比如当一台宿主机宕机时其上的所有容器都会产生告警。Alertmanager 可以将这些告警分组为一条“宿主机XX故障”的通知避免告警风暴。你还可以根据告警标签如teambackend将告警路由到不同的接收器如 Slack 频道、钉钉群、PagerDuty。Grafana 的极致可视化它的图表丰富、仪表板配置灵活并且完美支持 Prometheus 数据源。更重要的是Grafana 的仪表板可以 JSON 文件化方便版本管理和团队共享。注意这套组合并非银弹。Prometheus 默认是单机、无集群方案的数据按时间分片存储于本地。对于超大规模千万级时间序列或长期历史数据存储超过数月需要考虑 Thanos 或 Cortex 等扩展方案。但对于绝大多数场景单机 Prometheus 配合合理的保留策略如 30-90天完全够用。2.2 整体数据流与组件职责理解了“为什么选”再看“怎么连”。整个系统的数据流非常清晰[你的应用/节点/中间件] --(暴露指标)-- [Prometheus Server] --(抓取存储)-- [时序数据库] ^ | | v [告警规则] --(评估PromQL)--- [Prometheus Server] --(触发告警)-- [Alertmanager] --(路由分发)-- [邮件/Slack/钉钉/Webhook] | ^ v | [Grafana] ------------------------------------------------------------(数据查询)数据采集层各类 Exporters如 node_exporter 用于主机监控mysqld_exporter 用于 MySQL和应用自身埋点通过 Prometheus Client Library提供指标端点。存储与计算层Prometheus Server 是核心负责定时抓取、存储指标数据并根据配置的rules.yml持续评估告警规则。告警处理层Alertmanager 接收来自 Prometheus 的告警进行去噪、分组、路由并调用对应的接收器发送通知。可视化层Grafana 查询 Prometheus 的数据生成可视化的仪表板。这个架构的松耦合性很好每个组件都可以独立部署、升级和扩展。3. 一步步搭建你的监控告警栈理论说再多不如动手搭一遍。下面我以在 Linux 服务器上部署为例演示核心组件的安装与基础配置。假设我们的工作目录是/opt/monitoring。3.1 第一步部署 Prometheus ServerPrometheus 是核心我们先把它跑起来。下载与解压cd /opt/monitoring wget https://github.com/prometheus/prometheus/releases/download/v2.45.0/prometheus-2.45.0.linux-amd64.tar.gz tar xvf prometheus-2.45.0.linux-amd64.tar.gz ln -s prometheus-2.45.0.linux-amd64 prometheus # 创建软链接方便管理编写核心配置文件prometheus.yml 这是 Prometheus 的“大脑”定义了抓取谁、怎么抓、抓什么。# /opt/monitoring/prometheus/prometheus.yml global: scrape_interval: 15s # 默认抓取间隔 evaluation_interval: 15s # 告警规则评估间隔 # 告警规则文件路径 rule_files: - rules/*.yml # 我们将告警规则放在单独的rules目录下 # 抓取配置列表 scrape_configs: # 第一个任务监控 Prometheus 自身 - job_name: prometheus static_configs: - targets: [localhost:9090] # Prometheus 默认暴露在9090端口 # 第二个任务监控所有 Linux 服务器节点 - job_name: node static_configs: - targets: [192.168.1.101:9100, 192.168.1.102:9100] # node_exporter 默认端口9100 # 可以添加公共标签这些标签会附加到该job下所有抓取到的指标上 labels: env: production role: app-server这个配置定义了两个抓取任务Job监控自己以及监控两台 IP 为192.168.1.101和102的服务器需要在这些服务器上安装node_exporter。创建 systemd 服务文件以 CentOS/RHEL 为例 为了让 Prometheus 在后台稳定运行并开机自启我们将其托管给 systemd。# /etc/systemd/system/prometheus.service [Unit] DescriptionPrometheus Server Afternetwork.target [Service] Userprometheus # 建议创建一个专门的用户 Groupprometheus Typesimple ExecStart/opt/monitoring/prometheus/prometheus \ --config.file/opt/monitoring/prometheus/prometheus.yml \ --storage.tsdb.path/data/prometheus \ # 数据存储目录确保有权限 --web.enable-lifecycle # 允许通过API热重载配置 Restarton-failure [Install] WantedBymulti-user.target创建用户和数据目录sudo useradd --no-create-home --shell /bin/false prometheus sudo mkdir -p /data/prometheus sudo chown -R prometheus:prometheus /data/prometheus /opt/monitoring/prometheus sudo systemctl daemon-reload sudo systemctl start prometheus sudo systemctl enable prometheus现在访问http://你的服务器IP:9090就能看到 Prometheus 的 Web UI 了。在 “Status - Targets” 页面可以看到我们配置的两个抓取目标的状态。3.2 第二步在目标服务器部署 Node ExporterNode Exporter 用于收集主机层面的指标CPU、内存、磁盘、网络等。在需要监控的每台 Linux 服务器上执行# 在目标服务器如192.168.1.101上操作 cd /tmp wget https://github.com/prometheus/node_exporter/releases/download/v1.6.0/node_exporter-1.6.0.linux-amd64.tar.gz tar xvf node_exporter-*.tar.gz sudo mv node_exporter-*/node_exporter /usr/local/bin/同样创建 systemd 服务# /etc/systemd/system/node_exporter.service [Unit] DescriptionNode Exporter Afternetwork.target [Service] Usernobody Groupnobody Typesimple ExecStart/usr/local/bin/node_exporter Restarton-failure [Install] WantedBymulti-user.targetsudo systemctl daemon-reload sudo systemctl start node_exporter sudo systemctl enable node_exporter此时访问http://192.168.1.101:9100/metrics应该能看到大量的指标文本。回到 Prometheus 的 Targets 页面node这个 job 下的目标状态应该会变成 “UP”。3.3 第三步部署与配置 Alertmanager告警逻辑由 Prometheus 触发但由 Alertmanager 处理。下载与解压cd /opt/monitoring wget https://github.com/prometheus/alertmanager/releases/download/v0.25.0/alertmanager-0.25.0.linux-amd64.tar.gz tar xvf alertmanager-*.tar.gz ln -s alertmanager-0.25.0.linux-amd64 alertmanager配置alertmanager.yml 这里配置告警如何路由和通知。以下是一个配置示例将告警发送到 Slack 和邮件。# /opt/monitoring/alertmanager/alertmanager.yml global: smtp_smarthost: smtp.gmail.com:587 # 邮件SMTP服务器 smtp_from: your-alert-emailgmail.com smtp_auth_username: your-alert-emailgmail.com smtp_auth_password: your-app-specific-password # 注意使用应用专用密码 slack_api_url: https://hooks.slack.com/services/XXXX/YYYY/ZZZZ # Slack Webhook URL route: group_by: [alertname, env] # 按告警名和环境分组 group_wait: 10s # 同一分组内等待10秒再发送为了聚合同时发生的告警 group_interval: 10s repeat_interval: 1h # 如果告警持续未解决每小时重复发送一次 receiver: default-receiver routes: # 子路由可以更精细地控制 - match: severity: critical receiver: critical-receiver continue: true # 继续匹配后续路由 receivers: - name: default-receiver email_configs: - to: teamyourcompany.com send_resolved: true # 告警恢复时也发送通知 slack_configs: - channel: #monitoring-alerts title: {{ .GroupLabels.alertname }} text: |- *状态*: {{ .Status | toUpper }} *环境*: {{ .GroupLabels.env }} *摘要*: {{ .CommonAnnotations.summary }} *详情*: {{ .CommonAnnotations.description }} *链接*: {{ .GeneratorURL }}|Prometheus - name: critical-receiver slack_configs: - channel: #oncall-critical title: [CRITICAL] {{ .GroupLabels.alertname }} text: 需要立即关注{{ .CommonAnnotations.description }} webhook_configs: # 还可以触发电话、短信等Webhook - url: http://your-pager-service/hook这个配置定义了两个接收器Receiver并根据告警的severity标签进行路由。所有告警都会发到default-receiver邮件和 Slack 常规频道而标记为critical的告警会额外发送到critical-receiverSlack 紧急频道和可能的电话 Webhook。创建 systemd 服务并启动步骤同 Prometheus略。在 Prometheus 中配置 Alertmanager 修改prometheus.yml告诉 Prometheus 将触发的告警发送到哪里。# 在 prometheus.yml 的 global 部分后添加 alerting: alertmanagers: - static_configs: - targets: - localhost:9093 # Alertmanager 默认端口3.4 第四步部署 Grafana 并配置数据源Grafana 是我们的展示窗口。安装以 CentOS 为例sudo yum install -y https://dl.grafana.com/oss/release/grafana-9.5.2-1.x86_64.rpm sudo systemctl start grafana-server sudo systemctl enable grafana-serverGrafana 默认运行在3000端口初始账号密码是admin/admin。添加 Prometheus 数据源 登录 Grafana 后点击左侧齿轮图标 “Configuration” - “Data sources” - “Add data source”选择 Prometheus。在 URL 栏填写http://localhost:9090如果 Grafana 和 Prometheus 在同一台机器然后点击 “Save test”应该显示 “Data source is working”。导入仪表板 从头创建仪表板费时费力社区有大量现成的优秀模板。例如要导入著名的 “Node Exporter Full” 仪表板ID: 1860在 Grafana 首页点击 “” - “Import”。在 “Import via grafana.com” 框内输入1860点击 Load。选择刚才添加的 Prometheus 数据源点击 Import。 瞬间一个功能齐全的主机监控仪表板就出现了包含了 CPU、内存、磁盘 IO、网络流量等所有关键图表。4. 编写有灵魂的告警规则告警规则是监控系统的“大脑”规则写得好告警才有效否则就是噪音制造机。告警规则文件如rules/node_alerts.yml由 Prometheus 加载并定期评估。4.1 告警规则的结构与最佳实践一条完整的告警规则包含以下部分groups: - name: node.rules # 规则组名 rules: - alert: InstanceDown # 告警名称全局唯一 expr: up{jobnode} 0 # PromQL 表达式结果为布尔值 for: 1m # 持续时长避免瞬时抖动 labels: severity: critical # 自定义标签用于告警路由和分类 team: infra annotations: summary: 实例 {{ $labels.instance }} 下线 description: {{ $labels.instance }} ({{ $labels.job }}) 已超过1分钟无法访问。 runbook: http://wiki.internal/runbooks/instance-down # 关联的应急预案链接最佳实践与心得for字段是你的朋友一定要用。网络瞬时抖动、进程短暂重启都可能触发up0设置for: 1m或for: 2m可以过滤掉这些噪音显著减少误报。善用labels进行路由severitycritical, warning、teambackend, frontend, dba、envprod, staging这些标签是 Alertmanager 路由规则的依据。务必在规则里打上清晰的标签。annotations要包含 actionable 信息summary和description要清晰指出哪里出了问题、可能的原因、以及下一步做什么。好的告警信息能让 on-call 工程师在睡眼惺忪时也能快速行动。附上runbook应急预案链接是专业体现。避免“狼来了”效应不要为每一个小波动都设置告警。关注影响业务的指标可用性up、错误率5xx、延迟p99、饱和度磁盘使用率、内存使用率。基于 SLO服务水平目标来设定告警阈值比拍脑袋定一个 80% 更有意义。4.2 经典告警规则示例解析下面分享几个经过实战检验的规则groups: - name: host.rules rules: # 规则1主机失联 - alert: HostOutage expr: up{jobnode} 0 for: 2m labels: severity: critical annotations: summary: 主机失联: {{ $labels.instance }} description: Prometheus 无法在2分钟内从 {{ $labels.instance }} 抓取指标。请检查主机状态、网络及 node_exporter 进程。 # 规则2高内存使用率关注可用内存而非已用内存百分比 - alert: HostMemoryRunningLow expr: (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 10 for: 5m labels: severity: warning annotations: summary: 主机内存不足: {{ $labels.instance }} (可用内存低于10%) description: 实例 {{ $labels.instance }} 的可用内存比例已持续5分钟低于10%。当前值{{ $value | humanizePercentage }}。可能影响应用性能。 # 规则3磁盘空间即将耗尽预测性告警 - alert: DiskWillFillIn4Hours expr: predict_linear(node_filesystem_free_bytes{jobnode, mountpoint!~.*pod.*}[1h], 4*3600) 0 for: 5m labels: severity: warning annotations: summary: 磁盘空间预计4小时内耗尽: {{ $labels.instance }} {{ $labels.mountpoint }} description: 根据过去1小时的趋势挂载点 {{ $labels.mountpoint }} 的剩余空间预计将在4小时内耗尽。请立即清理。 # 规则4应用业务指标告警假设应用暴露了 http_requests_total 指标 - alert: HighErrorRate expr: sum(rate(http_requests_total{status~5..}[5m])) by (service, endpoint) / sum(rate(http_requests_total[5m])) by (service, endpoint) 0.05 for: 2m labels: severity: critical team: backend annotations: summary: 高错误率: {{ $labels.service }} - {{ $labels.endpoint }} description: 服务 {{ $labels.service }} 的端点 {{ $labels.endpoint }} 在过去5分钟内错误率超过5%。当前值{{ $value | humanizePercentage }}。请检查应用日志和依赖服务。规则解析与踩坑点HostMemoryRunningLow使用MemAvailable而不是100 - (MemFree/MemTotal)*100。因为 Linux 会利用空闲内存做缓存Cached和缓冲Buffers这部分内存是可被应用程序快速回收的。MemAvailable是内核估算的真正可用内存更准确。DiskWillFillIn4Hours使用了predict_linear函数进行线性预测。[1h]表示基于过去1小时的数据预测4小时4*3600秒后的值。这是一个非常实用的预测性告警能在问题发生前给你预留处理时间。注意用mountpoint!~.*pod.*排除了 Kubernetes Pod 挂载的临时卷。HighErrorRate这是一个典型的业务层告警。它计算的是5xx错误请求占总请求的比例。rate()函数计算每秒速率[5m]是时间窗口。通过by (service, endpoint)按服务和端点维度聚合能精确定位到出问题的具体API。将写好的规则文件如node_alerts.yml放在 Prometheus 配置中rule_files指定的目录例如rules/下然后通过curl -X POST http://localhost:9090/-/reload热重载 Prometheus 配置或者重启 Prometheus 服务。5. 高级配置与生产级优化基础搭建完成后要让这套系统真正扛起生产环境的大旗还需要一些优化和高级特性。5.1 服务发现告别手动维护IP列表在动态的云环境或容器环境中服务器的 IP 是变化的。我们不可能每次扩缩容都去修改prometheus.yml。Prometheus 支持多种服务发现机制。基于文件的服务发现最简单的一种。Prometheus 读取一个 JSON 或 YAML 文件来获取目标列表。你可以写一个脚本定期从 CMDB 或云厂商 API 拉取服务器列表生成这个文件。# prometheus.yml scrape_configs: - job_name: node file_sd_configs: - files: - /etc/prometheus/targets/node*.json # 可以匹配多个文件 refresh_interval: 5m # 每5分钟重新读取文件# /etc/prometheus/targets/nodes.json [ { targets: [ 10.0.1.12:9100, 10.0.1.13:9100 ], labels: { env: production, region: us-east-1 } } ]基于 Kubernetes 的服务发现如果你用 K8sPrometheus 可以自动发现 Service、Pod、Endpoint 等资源并为其添加丰富的标签如 namespace, pod name, container name。这是监控容器环境的利器配置稍复杂需要赋予 Prometheus 相应的 RBAC 权限。5.2 告警模板让通知信息更友好Alertmanager 支持使用 Go template 来定制告警通知的格式。你可以创建一个模板文件让 Slack 或邮件的告警信息更加结构化、易读。# alertmanager.yml templates: - /etc/alertmanager/templates/*.tmpl # 指定模板文件路径# /etc/alertmanager/templates/custom.tmpl {{ define slack.custom.title }}[{{ .Status | toUpper }}] {{ .GroupLabels.alertname }} {{ .GroupLabels.env }}{{ end }} {{ define slack.custom.text }} *告警状态*: {{ .Status | toUpper }} *告警名称*: {{ .GroupLabels.alertname }} *故障实例*: {{ .CommonLabels.instance }} *触发时间*: {{ .StartsAt.Format 2006-01-02 15:04:05 UTC }} {{ range .Annotations }} *{{ .Name }}*: {{ .Value }} {{ end }} {{ range .Alerts }} *告警指纹*: {{ .Fingerprint }} {{ end }} *Grafana仪表板*: http://grafana.yourcompany.com/d/abc123|点击查看相关面板 *应急预案*: {{ .CommonAnnotations.runbook }}|Runbook {{ end }}然后在slack_configs中引用这个模板slack_configs: - channel: #alerts title: {{ template slack.custom.title . }} text: {{ template slack.custom.text . }}5.3 记录规则预计算以提升查询效率当你的 PromQL 查询非常复杂或需要频繁查询时可能会给 Prometheus 服务器造成压力。记录规则Recording Rule允许你预先计算好这些复杂的表达式并将其结果保存为一个新的时间序列。这样Grafana 仪表板或告警规则直接查询这个新的、简单的指标即可。定义在rules/目录下的record_rules.yml中groups: - name: recording_rules interval: 30s # 计算间隔可不同于抓取间隔 rules: - record: job:http_requests:rate5m # 新指标名推荐带冒号的命名空间 expr: sum(rate(http_requests_total[5m])) by (job) - record: instance:node_cpu_utilisation:rate5m expr: 1 - avg(rate(node_cpu_seconds_total{modeidle}[5m])) by (instance)之后告警规则中就可以直接使用job:http_requests:rate5m 100这样的简单表达式而不是冗长的sum(rate(...))。5.4 监控 Prometheus 自身与 Alertmanager监控系统自身也必须被监控。除了基础的up指标还要关注Prometheus:prometheus_tsdb_head_samples_appended_total样本摄入速率突然下降可能意味着抓取故障。prometheus_target_skipped_scrapes_total跳过的抓取次数过多可能配置有问题。process_resident_memory_bytes进程常驻内存持续增长可能内存泄漏。prometheus_rule_group_duration_seconds规则评估耗时耗时过长会影响告警及时性。Alertmanager:alertmanager_notifications_total和alertmanager_notifications_failed_total通知发送成功/失败计数。alertmanager_alerts当前活跃告警数。为它们也创建 Grafana 仪表板和关键的告警规则比如 Prometheus 抓取失败、自身内存过高。6. 实战问题排查与维护心得系统跑起来只是开始日常维护和问题排查才是重头戏。这里记录几个典型场景和我的处理思路。6.1 常见问题速查表问题现象可能原因排查步骤Prometheus Targets 显示DOWN1. 网络不通/防火墙2. Exporter 进程未运行3. 抓取配置错误端口、路径1.telnet target_ip port测试连通性。2. 登录目标机systemctl status node_exporter。3. 检查 Prometheus 配置的targets和 Exporter 实际端口。Grafana 图表显示 “No data”1. 数据源配置错误2. PromQL 查询语法错误3. 时间范围选择不当1. 在 Grafana 数据源配置页点击 “Save test”。2. 复制查询语句到 Prometheus 的 Graph 页面测试。3. 检查时间选择器是否跳到了未来或很久以前。收不到告警通知1. Alertmanager 未运行或配置未加载2. 告警规则未触发for时长不够3. 路由/接收器配置错误4. SMTP/Slack Webhook 配置错误1. 访问http://alertmanager:9093查看 UI 和状态。2. 在 Prometheus 的 “Alerts” 标签页查看告警状态是否为 “Firing”。3. 在 Alertmanager 的 “Status” 页面检查配置。4. 查看 Alertmanager 日志journalctl -u alertmanager -f。告警信息不准确1. 告警规则表达式逻辑错误2. 指标标签不一致或缺失1. 在 Prometheus 的 Graph 页面手动执行告警表达式验证结果。2. 使用up{jobnode}或{__name__~.*}查看目标暴露的原始指标和标签。Prometheus 内存/磁盘占用高1. 抓取目标过多/指标基数Cardinality爆炸2. 数据保留时间过长3. 记录规则或告警规则过于复杂1. 使用prometheus_tsdb_head_series查看时间序列总数。检查是否有标签值过多如将用户ID作为标签。2. 调整--storage.tsdb.retention.time参数。3. 优化记录规则合并相似查询。6.2 性能调优与容量规划心得控制指标基数这是影响 Prometheus 性能的最关键因素。指标基数是指唯一时间序列的数量。避免将高基数的维度如用户ID、请求ID、SessionID作为标签。每增加一个标签值就会产生一条新的时间序列。如果必须记录考虑将其作为日志输出或使用其他更适合高基数数据的系统如 Elasticsearch/Loki。合理的抓取间隔不是越短越好。scrape_interval: 15s是平衡实时性和负载的常用值。对于变化不频繁的指标如磁盘容量可以设置为30s或60s。在scrape_configs的 job 或 target 级别可以覆盖全局设置。规划存储Prometheus 本地存储的默认路径是--storage.tsdb.path。确保该目录所在磁盘有足够空间和 IOPS。一个粗略的估算公式所需磁盘空间 抓取间隔时间 × 指标数量 × 保留天数 × 每个样本约1-2字节。实际上配合压缩通常每百万时间序列每小时约需要 1-2GB。使用远程读写对于长期存储或跨 Prometheus 实例聚合查询可以配置remote_write将数据发送到 VictoriaMetrics、Thanos Receiver 或商业 TSDB。配置remote_read可以从这些远程存储查询数据。这能有效减轻本地 Prometheus 的压力。6.3 告警疲劳应对策略告警太多等于没有告警。如何减少噪音分级与路由充分利用 Alertmanager 的routes和labels。将告警分为critical需要立即行动、warning需要关注但非紧急、info仅记录。critical发短信/电话warning发 Slack/邮件info可能只记录不通知。维护期与静默对于计划内的维护如系统升级提前在 Alertmanager 的 Web UI (http://alertmanager:9093) 上创建静默规则Silence指定匹配的标签如instance~host-.*和时间范围避免收到无关告警。依赖抑制在alertmanager.yml中配置inhibit_rules。例如当“宿主机宕机”告警触发时抑制所有来自该宿主机上容器的“容器无响应”告警。inhibit_rules: - source_match: alertname: HostOutage target_match: alertname: ContainerDown equal: [instance] # 当instance标签相同时抑制目标告警定期评审与优化每季度或每半年团队一起 Review 一次告警规则。哪些告警从未触发哪些频繁触发但从未导致故障哪些告警触发了但信息无用根据 Review 结果优化或删除规则。这是保持告警系统健康度的必要仪式。搭建和维护一套监控告警系统是一个持续迭代的过程。它始于技术选型与部署但最终的价值体现在能否真正赋能团队快速发现、定位并解决线上问题从而提升系统的整体稳定性和团队的研发效率。这套基于 Prometheus 的栈以其灵活性和强大的社区生态为我们提供了一个坚实的起点。剩下的就是在实践中不断打磨规则、优化视图让它越来越贴合你的业务脉搏。