13.9.4 日志与指标的告警策略

在 HAProxy 的告警策略设计中,应同时覆盖日志与指标两条信号链路,形成“异常发现—定位—升级—恢复”的闭环。日志侧侧重于行为异常与错误模式识别,指标侧关注容量、性能与可用性阈值触发。以下给出可落地的规则、示例、命令与排错路径。

一、原理草图:日志与指标双通道告警闭环

文章图片

二、日志告警策略(含示例与命令)
- 关键错误码与模式:5xx 激增、后端连接失败、健康检查失败、SSL 握手错误、连接被拒绝等。
- 频率阈值:滑动时间窗内同类错误超过阈值。
- 行为异常:异常重试、会话保持失效、过多 408/499。

示例:rsyslog 采集与简单阈值统计

目标:1 分钟内 5xx 超过 100 次触发告警(示例脚本)

1) HAProxy 日志输出(/etc/haproxy/haproxy.cfg):

global
  log 127.0.0.1 local0
  log 127.0.0.1 local1 notice

defaults
  mode http
  log global
  option httplog

2) rsyslog 记录到文件(/etc/rsyslog.d/49-haproxy.conf):

local0.* /var/log/haproxy.log
systemctl restart rsyslog

3) 统计 5xx 并触发告警(/usr/local/bin/haproxy_5xx_alert.sh):

#!/usr/bin/env bash
LOG=/var/log/haproxy.log
WINDOW=60
THRESHOLD=100
NOW=$(date +%s)
COUNT=$(awk -v now=$NOW -v win=$WINDOW '
  {
    # 示例中假设日志最后字段为 http_status
    # 需要根据你的日志格式调整字段
    ts=strftime("%s", systime())
    if ($0 ~ / 5[0-9][0-9] /) c++
  }
  END{print c+0}
' "$LOG")

if [ "$COUNT" -ge "$THRESHOLD" ]; then
  echo "ALERT: 5xx=$COUNT in last ${WINDOW}s" | logger -t haproxy_alert
fi
chmod +x /usr/local/bin/haproxy_5xx_alert.sh

排错要点
- 日志没写入:检查 rsyslog 是否启用 UDP 514、/etc/rsyslog.conf 是否允许接收。
- 5xx 统计不准:核对日志格式与字段位置(可用 tail -n 1 /var/log/haproxy.log 观察)。
- 告警风暴:脚本增加“告警抑制”(如 10 分钟内不重复告警)。

三、指标告警策略(Prometheus + Exporter)
- 可用性类:后端实例 DOWN 数、健康检查失败率。
- 性能类:QPS、连接数、队列长度、响应时间 P95/P99。
- 资源类:CPU、内存、FD、网络吞吐。
- 协议类:HTTP 4xx/5xx 比例、SSL 握手失败率。

安装与接入示例
1) 安装 haproxy-exporter(以二进制为例):

wget https://github.com/prometheus/haproxy_exporter/releases/download/v0.14.0/haproxy_exporter-0.14.0.linux-amd64.tar.gz
tar -zxvf haproxy_exporter-0.14.0.linux-amd64.tar.gz
cp haproxy_exporter-0.14.0.linux-amd64/haproxy_exporter /usr/local/bin/

2) 启用 HAProxy stats(/etc/haproxy/haproxy.cfg):

listen stats
  bind *:8404
  stats enable
  stats uri /stats
  stats refresh 10s
systemctl restart haproxy

3) 启动 exporter:

/usr/local/bin/haproxy_exporter \
  --haproxy.scrape-uri="http://127.0.0.1:8404/stats;csv" \
  --web.listen-address=":9101"

4) Prometheus 抓取配置(/etc/prometheus/prometheus.yml):

scrape_configs:
  - job_name: 'haproxy'
    static_configs:
      - targets: ['127.0.0.1:9101']

示例告警规则(/etc/prometheus/rules/haproxy.yml)

groups:
- name: haproxy.alerts
  rules:
  - alert: HAProxy_Backend_Down
    expr: haproxy_backend_up == 0
    for: 1m
    labels:
      severity: P0
    annotations:
      summary: "HAProxy 后端全部不可用"
      description: "backend={{ $labels.backend }}"

  - alert: HAProxy_5xx_High
    expr: rate(haproxy_frontend_http_responses_total{code=~"5.."}[1m]) > 5
    for: 2m
    labels:
      severity: P1
    annotations:
      summary: "5xx 错误率过高"
      description: "frontend={{ $labels.frontend }}"

排错要点
- exporter 无数据:访问 http://127.0.0.1:9101/metrics 检查是否返回指标。
- stats 访问失败:确认 8404 端口开放、stats enable 是否生效。
- 规则不触发:确认 Prometheus 已加载规则(/api/v1/rules)。

四、告警分级与响应策略(落地模板)
- P0:全站不可用、后端全部 DOWN、核心接口错误率突增(电话/IM 立即触达)。
- P1:可用性下降、关键服务响应时间显著升高(15 分钟内响应)。
- P2:局部错误、非核心业务异常(工单/值班处理)。
- P3:趋势性问题或单点偶发(纳入日常巡检)。

示例:Alertmanager 路由(/etc/alertmanager/alertmanager.yml)

route:
  receiver: 'default'
  routes:
  - match:
      severity: P0
    receiver: 'im_call'
  - match:
      severity: P1
    receiver: 'im'
receivers:
- name: 'im_call'
  webhook_configs:
  - url: 'http://im-call.example.com/notify'
- name: 'im'
  webhook_configs:
  - url: 'http://im.example.com/notify'
- name: 'default'
  email_configs:
  - to: 'ops@example.com'

五、告警收敛与降噪(示例配置与策略)
- 聚合与去重:同类告警按 backend/instance 聚合。
- 延迟触发:短暂抖动用 for 参数抑制误报。
- 依赖抑制:基础设施故障时抑制上层。

示例:Prometheus 规则延迟与聚合

- alert: HAProxy_Conn_Queue_High
  expr: haproxy_backend_queue > 100
  for: 5m
  labels:
    severity: P2
  annotations:
    summary: "后端队列堆积"

六、快速排障命令清单

# 查看 HAProxy 日志
tail -f /var/log/haproxy.log

# 查看 stats 页面是否可访问
curl -s http://127.0.0.1:8404/stats | head -n 5

# exporter 指标
curl -s http://127.0.0.1:9101/metrics | head -n 5

# 当前连接与会话状态
echo "show stat" | socat stdio /run/haproxy/admin.sock

七、练习
1) 配置日志告警:在 1 分钟内 5xx 超过 50 次触发告警,并将告警写入 syslog。
2) 配置指标告警:后端实例 down 超过 1 台告警;P95 响应时间超过 500ms 告警。
3) 误报处理:为 5xx 告警加上 for: 2m,观察告警触发变化。
4) 故障演练:手动停止后端服务,验证告警升级与恢复闭环是否完整。