Prometheus Alertmanager 高级告警规则与 PHP 应用静默策略配置
各位同学,大家好。今天我们来深入探讨如何使用 Prometheus Alertmanager 为 PHP 应用配置高级告警规则和静默策略。
首先,我们需要明确目标:不仅仅是简单的告警,而是能够根据 PHP 应用的实际运行状态,精确识别问题,并针对不同问题采取不同的处理策略。这包括告警的优先级划分、告警通知的路由、以及在特定情况下抑制告警。
一、Prometheus 告警规则的设计原则
好的告警规则应该具备以下特点:
- 可操作性 (Actionable): 告警信息应该包含足够的信息,让运维人员能够快速定位问题并采取行动。
- 准确性 (Accuracy): 避免产生误报和漏报。误报会浪费运维资源,漏报会导致问题扩大。
- 及时性 (Timeliness): 告警应该在问题发生后尽快发出,以便及时处理。
- 简洁性 (Simplicity): 告警规则应该简单易懂,方便维护和调试。
二、PHP 应用的监控指标选择
为了设计有效的告警规则,我们需要选择合适的监控指标。以下是一些常用的 PHP 应用监控指标:
| 指标名称 | 指标类型 | 描述 | 采集方式 |
|---|---|---|---|
php_fpm_process_active |
Gauge | 当前活跃的 PHP-FPM 进程数 | 使用 PHP-FPM 的状态页面 (status page) 或者 Prometheus Exporter |
php_fpm_process_idle |
Gauge | 当前空闲的 PHP-FPM 进程数 | 使用 PHP-FPM 的状态页面或者 Prometheus Exporter |
php_fpm_process_max_children |
Gauge | PHP-FPM 允许的最大子进程数 | 使用 PHP-FPM 的状态页面或者 Prometheus Exporter |
php_fpm_request_duration_seconds |
Histogram | PHP 请求处理时间分布 | 使用 PHP-FPM 的状态页面或者 Prometheus Exporter,或者通过 OpenTelemetry 在应用代码中埋点 |
http_requests_total |
Counter | HTTP 请求总数 | 使用 Web 服务器 (如 Nginx, Apache) 的监控模块,或者通过 OpenTelemetry 在应用代码中埋点 |
http_request_duration_seconds |
Histogram | HTTP 请求处理时间分布 | 使用 Web 服务器的监控模块,或者通过 OpenTelemetry 在应用代码中埋点 |
mysql_connections_active |
Gauge | 当前活跃的 MySQL 连接数 | 使用 MySQL 的状态变量 (SHOW STATUS) 或者 Prometheus Exporter |
mysql_query_duration_seconds |
Histogram | MySQL 查询执行时间分布 | 使用 MySQL 的慢查询日志分析,或者通过 OpenTelemetry 在应用代码中埋点 |
redis_connected_clients |
Gauge | 当前连接到 Redis 的客户端数量 | 使用 Redis 的 INFO 命令或者 Prometheus Exporter |
redis_command_duration_seconds |
Histogram | Redis 命令执行时间分布 | 使用 Redis 的 MONITOR 命令分析,或者通过 OpenTelemetry 在应用代码中埋点 |
php_errors_total |
Counter | PHP 错误总数 | 通过 PHP 的错误日志分析,或者使用错误处理机制记录到 Prometheus Exporter |
php_exceptions_total |
Counter | PHP 异常总数 | 通过 PHP 的异常处理机制记录到 Prometheus Exporter |
cache_hit_ratio |
Gauge | 缓存命中率 | 根据使用的缓存系统 (如 Redis, Memcached) 的监控指标计算 |
queue_length |
Gauge | 消息队列长度 | 根据使用的消息队列系统 (如 RabbitMQ, Kafka) 的监控指标 |
cpu_usage_percent |
Gauge | CPU 使用率 | 使用 node_exporter 等系统监控工具 |
memory_usage_percent |
Gauge | 内存使用率 | 使用 node_exporter 等系统监控工具 |
disk_usage_percent |
Gauge | 磁盘使用率 | 使用 node_exporter 等系统监控工具 |
load_average |
Gauge | 系统负载 | 使用 node_exporter 等系统监控工具 |
file_descriptor_usage |
Gauge | 文件描述符使用量 | 使用 node_exporter 等系统监控工具 |
network_traffic_bytes_total |
Counter | 网络流量 | 使用 node_exporter 等系统监控工具 |
三、Prometheus 告警规则示例
下面是一些基于上述指标的告警规则示例,使用 Prometheus 的 PromQL 语法编写。
1. PHP-FPM 进程耗尽告警:
groups:
- name: php-fpm
rules:
- alert: PHPFPMProcessExhaustion
expr: php_fpm_process_active == php_fpm_process_max_children
for: 1m
labels:
severity: critical
annotations:
summary: "PHP-FPM 进程耗尽"
description: "PHP-FPM 活跃进程数已达到最大进程数,可能导致请求处理延迟。"
这条规则表示,如果 PHP-FPM 的活跃进程数等于最大进程数,持续 1 分钟,则触发一个 critical 级别的告警。告警信息包含摘要和详细描述,方便运维人员快速了解问题。
2. HTTP 请求延迟告警:
groups:
- name: http
rules:
- alert: HTTPRequestLatencyHigh
expr: histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le)) > 1
for: 1m
labels:
severity: warning
annotations:
summary: "HTTP 请求延迟过高"
description: "99% 的 HTTP 请求处理时间超过 1 秒。"
这条规则表示,如果过去 5 分钟内 99% 的 HTTP 请求处理时间超过 1 秒,持续 1 分钟,则触发一个 warning 级别的告警。
3. MySQL 连接数过高告警:
groups:
- name: mysql
rules:
- alert: MySQLHighConnectionCount
expr: mysql_connections_active > 100
for: 1m
labels:
severity: warning
annotations:
summary: "MySQL 连接数过高"
description: "MySQL 活跃连接数超过 100。"
这条规则表示,如果 MySQL 的活跃连接数超过 100,持续 1 分钟,则触发一个 warning 级别的告警。
4. PHP 错误率升高告警:
groups:
- name: php
rules:
- alert: PHPErrorRateHigh
expr: rate(php_errors_total[5m]) > 10
for: 1m
labels:
severity: warning
annotations:
summary: "PHP 错误率升高"
description: "过去 5 分钟内 PHP 错误率超过 10 个/分钟。"
这条规则表示,如果过去 5 分钟内 PHP 错误率超过 10 个/分钟,持续 1 分钟,则触发一个 warning 级别的告警。
5. Redis 响应时间过长告警:
groups:
- name: redis
rules:
- alert: RedisLatencyHigh
expr: histogram_quantile(0.95, sum(rate(redis_command_duration_seconds_bucket[5m])) by (le)) > 0.1
for: 1m
labels:
severity: warning
annotations:
summary: "Redis 响应时间过长"
description: "过去 5 分钟内 95% 的 Redis 命令执行时间超过 0.1 秒。"
这条规则表示,如果过去 5 分钟内 95% 的 Redis 命令执行时间超过 0.1 秒,持续 1 分钟,则触发一个 warning 级别的告警。
四、Alertmanager 配置:路由与通知
Alertmanager 的核心功能是路由告警并发送通知。我们需要配置 Alertmanager 的配置文件 (alertmanager.yml) 来定义路由规则和通知方式。
1. 路由规则:
路由规则决定了哪些告警应该发送到哪个接收器 (receiver)。路由规则基于告警的标签 (labels) 进行匹配。
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 1h
routes:
- match:
severity: 'critical'
receiver: 'slack-critical'
- match:
severity: 'warning'
receiver: 'email-team'
- match:
alertname: 'HTTPRequestLatencyHigh'
receiver: 'pagerduty-http'
这个配置定义了以下路由规则:
- 所有
critical级别的告警都发送到slack-critical接收器。 - 所有
warning级别的告警都发送到email-team接收器。 - 所有
alertname为HTTPRequestLatencyHigh的告警都发送到pagerduty-http接收器。
group_by,group_wait,group_interval,repeat_interval 等参数用于控制告警分组和通知频率,避免大量重复通知。
2. 接收器 (Receiver):
接收器定义了告警通知的发送方式。Alertmanager 支持多种通知方式,包括电子邮件、Slack、PagerDuty 等。
receivers:
- name: 'slack-critical'
slack_configs:
- api_url: 'https://hooks.slack.com/services/YOUR_SLACK_WEBHOOK_URL'
channel: '#critical-alerts'
send_resolved: true
- name: 'email-team'
email_configs:
- to: '[email protected]'
from: '[email protected]'
smarthost: 'smtp.example.com:587'
auth_username: 'alertmanager'
auth_password: 'YOUR_SMTP_PASSWORD'
send_resolved: true
- name: 'pagerduty-http'
pagerduty_configs:
- service_key: 'YOUR_PAGERDUTY_SERVICE_KEY'
send_resolved: true
这个配置定义了三个接收器:
slack-critical: 将告警发送到 Slack 的#critical-alerts频道。email-team: 将告警发送到[email protected]邮箱。pagerduty-http: 将告警发送到 PagerDuty。
send_resolved: true 表示在问题解决后发送恢复通知。
五、Alertmanager 静默策略
静默策略用于在特定情况下抑制告警。例如,在进行维护操作时,可以设置静默策略来避免产生不必要的告警。
1. 基于时间段的静默:
可以通过 Alertmanager 的 Web 界面或者 API 创建基于时间段的静默策略。例如,可以设置在每周六凌晨 2 点到 4 点之间,抑制所有与数据库相关的告警。
2. 基于标签的静默:
可以使用标签来定义更精细的静默策略。例如,可以设置当某个特定的服务处于维护模式时,抑制该服务的所有告警。
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'instance']
这个配置定义了一条抑制规则:如果存在一个 critical 级别的告警,并且与一个 warning 级别的告警的 alertname 和 instance 标签相同,则抑制该 warning 级别的告警。这可以避免在已经存在 critical 级别告警的情况下,重复发送 warning 级别的告警。
3. 使用 API 创建静默策略:
Alertmanager 提供了 API 用于创建、更新和删除静默策略。可以使用 curl 或者其他 HTTP 客户端来调用 API。
例如,可以使用以下命令创建一个静默策略,抑制所有 instance 标签为 php-app-01 的告警:
curl -X POST -H "Content-Type: application/json" -d '{
"matchers": [
{
"name": "instance",
"value": "php-app-01",
"isRegex": false
}
],
"startsAt": "2023-10-27T10:00:00Z",
"endsAt": "2023-10-27T12:00:00Z",
"createdBy": "admin",
"comment": "Maintenance on php-app-01"
}' http://localhost:9093/api/v2/silences
六、PHP 应用代码中的监控埋点
除了使用现有的监控工具,我们还可以在 PHP 应用代码中添加自定义的监控埋点,以获取更详细的应用运行状态信息。
1. 使用 OpenTelemetry:
OpenTelemetry 是一个开源的可观测性框架,可以用于收集和导出各种监控数据,包括 Metrics, Traces, Logs。
首先,需要安装 OpenTelemetry PHP SDK:
composer require open-telemetry/sdk
然后,在代码中添加监控埋点:
<?php
use OpenTelemetryAPIMetricsMeterInterface;
use OpenTelemetrySDKMetricsMeterProvider;
use OpenTelemetrySDKResourceResourceInfo;
use OpenTelemetrySDKResourceResourceAttributes;
use OpenTelemetrySemConvResourceAttributes as SemConvAttributes;
use OpenTelemetrySDKMetricsExportersConsoleExporter;
use OpenTelemetrySDKMetricsProcessorsConsoleMetricReader;
use OpenTelemetrySDKMetricsTemporality;
// Create a resource.
$resource = ResourceInfo::create(new ResourceAttributes([
SemConvAttributes::SERVICE_NAME => 'my-php-app',
SemConvAttributes::SERVICE_VERSION => '1.0.0',
]));
// Create a console exporter.
$exporter = new ConsoleExporter();
// Create a console metric reader.
$metricReader = new ConsoleMetricReader(
$exporter,
Temporality::DELTA, //or Temporality::CUMULATIVE
);
// Create a meter provider.
$meterProvider = MeterProvider::builder()
->addReader($metricReader)
->setResource($resource)
->build();
// Obtain a meter from the meter provider.
$meter = $meterProvider->getMeter('my-instrumentation-library', '0.1.0');
// Create a counter.
$counter = $meter->createCounter('my_counter');
// Add to the counter.
$counter->add(1, ['environment' => 'production']);
// Simulate some work
usleep(100000); // 0.1 seconds
// Shutdown the meter provider.
$meterProvider->shutdown();
echo "Metrics exported to console. Check your terminal output.n";
?>
这段代码创建了一个名为 my_counter 的计数器,并在每次请求处理时增加计数器的值。OpenTelemetry 会自动收集这些指标,并将其导出到 Prometheus。
2. 自定义 Prometheus Exporter:
如果没有使用 OpenTelemetry,也可以手动创建一个 Prometheus Exporter,将应用的监控指标暴露给 Prometheus。
创建一个 PHP 脚本,用于收集应用的监控指标:
<?php
// metrics.php
header('Content-Type: text/plain');
// 模拟一些指标数据
$active_users = rand(100, 200);
$request_duration = rand(10, 50);
$errors_total = rand(0, 5);
// 构建 Prometheus 指标格式
$output = "# HELP php_app_active_users 当前活跃用户数n";
$output .= "# TYPE php_app_active_users gaugen";
$output .= "php_app_active_users " . $active_users . "n";
$output .= "# HELP php_app_request_duration_ms 请求处理时间 (毫秒)n";
$output .= "# TYPE php_app_request_duration_ms gaugen";
$output .= "php_app_request_duration_ms " . $request_duration . "n";
$output .= "# HELP php_app_errors_total 错误总数n";
$output .= "# TYPE php_app_errors_total countern";
$output .= "php_app_errors_total " . $errors_total . "n";
echo $output;
?>
然后,配置 Prometheus 从该脚本中抓取指标:
scrape_configs:
- job_name: 'php-app'
scrape_interval: 5s
static_configs:
- targets: ['php-app-01:8080']
metrics_path: /metrics.php
七、最佳实践与注意事项
- 持续优化告警规则: 根据实际情况调整告警规则,避免误报和漏报。
- 使用标签进行分类: 使用标签对告警进行分类,方便路由和过滤。
- 监控关键业务指标: 优先监控对业务影响最大的指标。
- 定期审查静默策略: 确保静默策略不会影响重要的告警。
- 保持 Alertmanager 配置的清洁: 定期清理不再使用的路由规则和接收器。
告警和静默策略的有效使用
通过 Prometheus 和 Alertmanager,我们可以构建一个强大的告警系统,及时发现和解决 PHP 应用的问题。关键在于选择合适的监控指标,设计准确的告警规则,并配置合理的路由和静默策略。持续监控和调整,才能保证告警系统的有效性。