一、为什么爬虫必须建设可观测体系
在大规模分布式爬虫场景中,爬虫节点分散、任务周期长、反爬策略多变,传统的日志排查与人工巡检模式已无法满足运维需求。一个爬虫任务静默失败、请求成功率骤降、节点内存溢出,往往数小时后才能被发现,直接导致数据产出延迟、业务链路中断。
建设一套完整的监控告警体系,本质上是为爬虫系统装上 "眼睛" 和 "预警雷达":
- 实时感知:秒级掌握所有爬虫节点的运行状态、请求量、错误率
- 快速定位:通过指标维度下钻,快速定位是网络问题、反爬封禁还是代码异常
- 主动预警:在故障影响业务前触发告警,争取处置时间
- 容量规划:基于历史指标趋势,合理调度资源与扩展节点
Prometheus 作为云原生时代的时序监控标准,搭配 Grafana 的可视化能力与 Alertmanager 的告警路由,构成了企业级爬虫监控的黄金组合。本文将从架构设计、指标定义、部署落地到告警配置,完整呈现一套可直接复用的实战方案。
二、整体架构设计
2.1 技术栈选型
爬虫监控体系采用经典的 Pull 采集模式,整体架构分层如下:
表格
| 层级 | 组件 | 职责 |
|---|---|---|
| 采集层 | 爬虫客户端 + prometheus_client | 业务指标埋点与暴露 |
| 中转层 | Pushgateway(可选) | 短生命周期爬虫任务的指标推送 |
| 存储层 | Prometheus Server | 时序数据抓取、存储与 PromQL 查询 |
| 告警层 | Alertmanager | 告警分组、去重、路由与通知 |
| 可视化层 | Grafana | 仪表盘搭建、数据可视化与统一视图 |
| 基础设施层 | Node Exporter | 服务器 CPU、内存、磁盘、网络监控 |
2.2 架构数据流
- 每个爬虫进程内置 Prometheus 客户端库,在本地端口暴露
/metrics端点 - Prometheus Server 按配置周期主动拉取所有爬虫节点的指标数据
- 短时任务(如一次性爬虫脚本)通过 Pushgateway 推送指标
- Grafana 以 Prometheus 为数据源,通过 PromQL 查询渲染仪表盘
- Prometheus 根据告警规则评估状态,将告警推送至 Alertmanager
- Alertmanager 按级别路由到钉钉、企业微信、邮件、短信等通知渠道
对于分布式爬虫集群,可进一步采用 Prometheus 联邦集群模式,由中心节点汇聚各区域子节点的数据,实现统一全局视图。
三、爬虫核心监控指标设计
指标设计是监控体系的灵魂。针对爬虫业务特性,我们将指标分为四大类,覆盖基础设施、请求链路、业务产出、异常状态四个维度。
3.1 指标类型与适用场景
Prometheus 提供四种核心指标类型,需根据业务语义合理选择:
- Counter(计数器):单调递增,适用于请求总数、错误总数、Item 产出总数等累积量
- Gauge(仪表盘):可增可减,适用于活跃任务数、队列长度、内存占用等瞬时状态
- Histogram(直方图):分桶统计分布,适用于请求延迟、响应体大小等分布型数据
- Summary(摘要):客户端预计算分位数,适用于需要精准分位数的延迟统计
3.2 爬虫业务指标清单
请求链路指标
表格
| 指标名称 | 类型 | 标签 | 说明 |
|---|---|---|---|
crawler_requests_total |
Counter | spider, method, domain, status | 总请求数,按爬虫名、方法、域名、状态码分组 |
crawler_request_duration_seconds |
Histogram | spider, domain | 请求耗时分布,默认分桶 0.005~10s |
crawler_retries_total |
Counter | spider, domain, reason | 重试总次数,按重试原因分组(超时、状态码、代理失败) |
crawler_proxy_usage_total |
Counter | spider, proxy_pool | 代理使用次数统计 |
业务产出指标
表格
| 指标名称 | 类型 | 标签 | 说明 |
|---|---|---|---|
crawler_items_total |
Counter | spider, item_type | 抓取成功的 Item 总数 |
crawler_items_parse_errors_total |
Counter | spider, error_type | 解析失败次数,按错误类型分组 |
crawler_queue_depth |
Gauge | spider, queue_name | 任务队列当前长度 |
运行状态指标
表格
| 指标名称 | 类型 | 标签 | 说明 |
|---|---|---|---|
crawler_active_tasks |
Gauge | spider, node | 当前活跃任务数 |
crawler_memory_usage_bytes |
Gauge | spider, node | 爬虫进程内存占用 |
crawler_uptime_seconds |
Gauge | spider, node | 进程连续运行时长 |
crawler_banned_count_total |
Counter | spider, domain | 被反爬封禁的次数统计 |
基础设施指标
通过 Node Exporter 采集服务器基础指标:CPU 使用率、内存使用率、磁盘使用率、网络吞吐、TCP 连接数等,用于排查硬件资源瓶颈。
3.3 指标设计原则
- 标签克制:避免高基数标签(如将完整 URL 作为标签),防止 Prometheus 存储爆炸
- 原子埋点:只记录最细粒度事件,通过 PromQL 在查询时灵活聚合
- 命名规范 :遵循
namespace_subsystem_name_unit命名约定,保持全局一致性 - 可告警性:每个核心指标都应能支撑告警规则,避免无意义的装饰性指标
四、环境部署实战
4.1 Prometheus 部署
二进制安装(Linux)
bash
运行
# 下载稳定版
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
cd prometheus-2.45.0.linux-amd64
# 配置文件 prometheus.yml
cat > prometheus.yml << 'EOF'
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets: ['localhost:9093']
rule_files:
- "rules/*.yml"
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'crawler-nodes'
scrape_interval: 10s
static_configs:
- targets:
- '10.0.1.10:9091'
- '10.0.1.11:9091'
- '10.0.1.12:9091'
labels:
cluster: 'crawler-prod'
- job_name: 'node-exporter'
static_configs:
- targets:
- '10.0.1.10:9100'
- '10.0.1.11:9100'
EOF
# 后台启动
mkdir -p rules
nohup ./prometheus --config.file=prometheus.yml --storage.tsdb.retention.time=30d &
启动后访问 http://<服务器IP>:9090 可进入 Prometheus 自带 Web 界面,在 Targets 页面可查看所有采集端点的健康状态。
4.2 Node Exporter 部署
在每台爬虫宿主机安装 Node Exporter,采集系统指标:
bash
运行
wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz
tar xvf node_exporter-1.7.0.linux-amd64.tar.gz
cd node_exporter-1.7.0.linux-amd64
nohup ./node_exporter &
4.3 Grafana 部署
bash
运行
# Docker 方式(推荐)
docker run -d \
--name=grafana \
-p 3000:3000 \
-v grafana_data:/var/lib/grafana \
-e GF_SECURITY_ADMIN_PASSWORD=admin123 \
--restart=unless-stopped \
grafana/grafana:10.2.0
访问 http://<服务器IP>:3000,默认账号 admin/admin123。进入后添加 Prometheus 数据源:
- 左侧菜单 → Connections → Data sources → Add data source
- 选择 Prometheus,填入 URL:
http://<PrometheusIP>:9090 - 点击 Save & test 验证连接
4.4 Alertmanager 部署
bash
运行
wget https://github.com/prometheus/alertmanager/releases/download/v0.26.0/alertmanager-0.26.0.linux-amd64.tar.gz
tar xvf alertmanager-0.26.0.linux-amd64.tar.gz
cd alertmanager-0.26.0.linux-amd64
配置告警路由与通知渠道详见本文第七章。
五、爬虫端指标埋点实战
5.1 Scrapy 框架接入
Scrapy 生态有成熟的 scrapy-prometheus-exporter 插件,可快速接入监控体系:
bash
运行
pip install scrapy-prometheus-exporter
在 Scrapy 项目的 settings.py 中启用中间件:
python
运行
DOWNLOADER_MIDDLEWARES = {
'scrapy_prometheus_exporter.PrometheusMiddleware': 543,
}
PROMETHEUS_ENABLED = True
PROMETHEUS_PORT = 9091
PROMETHEUS_PATH = '/metrics'
启动爬虫后,访问 http://<节点IP>:9091/metrics 即可看到默认暴露的指标,包括请求总数、响应码分布、下载延迟等核心数据。
如需补充业务指标,可在爬虫代码中自定义扩展:
python
运行
from prometheus_client import Counter, Gauge
# 自定义指标
ITEM_PARSED = Counter('crawler_items_parsed_total', '解析成功的条目数', ['spider', 'category'])
BANNED_COUNT = Counter('crawler_banned_total', '被封禁次数', ['spider', 'domain'])
QUEUE_SIZE = Gauge('crawler_queue_size', 'Redis任务队列长度', ['queue_name'])
# 在解析回调中埋点
def parse(self, response):
ITEM_PARSED.labels(spider=self.name, category='detail').inc()
# 业务逻辑...
5.2 通用 Python 爬虫接入
对于基于 requests/aiohttp 的自研爬虫,使用 prometheus_client 库手动埋点:
python
运行
import time
import requests
from prometheus_client import start_http_server, Counter, Histogram, Gauge
# 定义指标
REQUEST_TOTAL = Counter(
'crawler_requests_total',
'Total crawler requests',
['spider_name', 'domain', 'status']
)
REQUEST_DURATION = Histogram(
'crawler_request_duration_seconds',
'Request duration in seconds',
['spider_name', 'domain'],
buckets=[0.01, 0.05, 0.1, 0.5, 1, 3, 5, 10]
)
ACTIVE_TASKS = Gauge(
'crawler_active_tasks',
'Number of active crawling tasks',
['spider_name']
)
# 启动 metrics 服务
start_http_server(9091)
def fetch_url(url, spider_name, domain):
ACTIVE_TASKS.labels(spider_name).inc()
start_time = time.time()
try:
resp = requests.get(url, timeout=10)
status = str(resp.status_code)
return resp
except Exception as e:
status = 'error'
raise
finally:
elapsed = time.time() - start_time
REQUEST_TOTAL.labels(spider_name, domain, status).inc()
REQUEST_DURATION.labels(spider_name, domain).observe(elapsed)
ACTIVE_TASKS.labels(spider_name).dec()
5.3 短时任务与 Pushgateway
对于执行时间短、进程退出快的一次性爬虫脚本,Pull 模式无法采集,需使用 Pushgateway 中转:
python
运行
from prometheus_client import CollectorRegistry, Gauge, push_to_gateway
registry = CollectorRegistry()
items_count = Gauge('crawler_batch_items_total', 'Batch items count', registry=registry)
items_count.set(1523)
push_to_gateway('10.0.1.10:9091', job='daily_batch_spider', registry=registry)
Prometheus 配置中增加 Pushgateway 采集任务即可。
六、Grafana 可视化仪表盘搭建
6.1 仪表盘整体布局
推荐搭建三层仪表盘体系:
- 总览大盘:全集群请求量、成功率、错误率、活跃节点、Item 产出速率
- 单爬虫详情:单个爬虫任务的请求趋势、延迟分布、域名维度拆解
- 主机监控:服务器 CPU、内存、磁盘、网络的资源使用情况
6.2 关键 PromQL 语句
以下是爬虫监控中最常用的 PromQL 查询,可直接用于 Grafana 面板:
1. 每秒请求数(QPS)
promql
sum(rate(crawler_requests_total[5m])) by (spider)
2. 请求成功率
promql
sum(rate(crawler_requests_total{status=~"2.."}[5m]))
/
sum(rate(crawler_requests_total[5m]))
3. 错误率(按域名分组)
promql
sum(rate(crawler_requests_total{status=~"5..|4..|error"}[5m])) by (domain)
/
sum(rate(crawler_requests_total[5m])) by (domain)
4. 95 分位请求延迟
promql
histogram_quantile(0.95, sum(rate(crawler_request_duration_seconds_bucket[5m])) by (le, spider))
5. Item 产出速率
promql
rate(crawler_items_total[5m])
6. 活跃任务数
promql
crawler_active_tasks
6.3 仪表盘配置建议
- 使用 Stat 面板展示核心 KPI:总请求量、成功率、平均延迟、Item 产出数
- 使用 Time series 面板展示趋势曲线,支持多维度对比
- 使用 Bar chart 面板展示各域名 / 各爬虫的请求量排行
- 使用 Gauge 面板展示成功率、资源使用率等百分比指标
- 配置变量(Variable)支持按爬虫名、节点、域名进行筛选下钻
可直接导入 Node Exporter 官方仪表盘(ID: 1860)作为基础设施监控面板,在此基础上叠加爬虫业务指标。
七、告警规则与通知体系
7.1 核心告警规则
在 Prometheus 的 rules/crawler-alerts.yml 中配置告警规则:
yaml
groups:
- name: crawler-alerts
rules:
# 爬虫节点宕机
- alert: CrawlerNodeDown
expr: up{job="crawler-nodes"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "爬虫节点 {{ $labels.instance }} 离线"
description: "节点已超过1分钟无法采集指标"
# 请求错误率过高
- alert: HighErrorRate
expr: |
sum(rate(crawler_requests_total{status=~"5..|error"}[5m]))
/
sum(rate(crawler_requests_total[5m])) > 0.1
for: 5m
labels:
severity: warning
annotations:
summary: "爬虫请求错误率超过10%"
description: "当前错误率: {{ $value | printf \"%.2f\" }}%"
# 请求成功率骤降
- alert: SuccessRateDrop
expr: |
(sum(rate(crawler_requests_total{status=~"2.."}[5m]))
/
sum(rate(crawler_requests_total[5m]))) < 0.8
for: 3m
labels:
severity: critical
annotations:
summary: "爬虫成功率骤降至80%以下"
description: "爬虫 {{ $labels.spider }} 成功率异常,当前值: {{ $value | printf \"%.2f\" }}%"
# 队列堆积
- alert: QueueBacklog
expr: crawler_queue_depth > 10000
for: 10m
labels:
severity: warning
annotations:
summary: "任务队列严重堆积"
description: "队列 {{ $labels.queue_name }} 当前长度: {{ $value }}"
# 内存使用率过高
- alert: HighMemoryUsage
expr: (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 > 85
for: 5m
labels:
severity: warning
annotations:
summary: "主机 {{ $labels.instance }} 内存使用率过高"
description: "当前内存使用率: {{ $value | printf \"%.1f\" }}%"
7.2 Alertmanager 配置
alertmanager.yml 配置告警分级路由与通知渠道:
yaml
global:
resolve_timeout: 5m
route:
group_by: ['alertname', 'cluster']
group_wait: 10s
group_interval: 5m
repeat_interval: 4h
receiver: 'default-webhook'
routes:
- match:
severity: critical
receiver: 'dingtalk-critical'
repeat_interval: 30m
- match:
severity: warning
receiver: 'dingtalk-warning'
repeat_interval: 2h
receivers:
- name: 'dingtalk-critical'
webhook_configs:
- url: 'http://your-dingtalk-webhook-url/critical'
send_resolved: true
- name: 'dingtalk-warning'
webhook_configs:
- url: 'http://your-dingtalk-webhook-url/warning'
send_resolved: true
7.3 告警治理最佳实践
- 分级告警:Critical 级走电话 / 短信 + 钉钉,Warning 级仅钉钉通知,避免告警疲劳
- 抑制规则:节点宕机时自动抑制该节点上的所有业务告警
- 静默管理:发布变更、维护窗口期提前设置静默,避免无效告警
- 告警复盘:定期梳理告警,消除噪声告警,持续优化阈值
八、生产环境优化建议
8.1 性能与存储优化
- 保留策略:根据业务需求设置合理的保留时间,默认 15~30 天,长期数据建议接入 Thanos 或 VictoriaMetrics
- 采样降精度:历史数据可通过 downsampling 降低精度,节省存储空间
- 标签基数控制:严格控制标签取值数量,禁止将 URL、用户 ID 等高基数字段作为标签
- 联邦集群:爬虫节点超过 50 个时,建议按地域 / 业务线拆分子 Prometheus,由中心节点联邦汇聚
8.2 安全加固
- Prometheus 与 Grafana 不直接暴露公网,通过内网或 VPN 访问
- 开启 Grafana 登录认证与权限控制,区分管理员与只读用户
- 爬虫 metrics 端点增加 IP 白名单或 Basic Auth 认证
- Alertmanager 通知渠道使用加密 Webhook
8.3 高可用部署
生产环境建议采用双节点主备模式:
- 两套 Prometheus 并行采集相同目标,互为备份
- Alertmanager 集群部署,避免单点故障
- Grafana 挂载共享数据库(PostgreSQL/MySQL),实现多实例无状态部署
九、总结
爬虫监控告警体系的建设,是爬虫工程化成熟度的重要标志。从 "跑起来" 到 "跑得稳、可观测、可预警",本质上是从脚本思维向工程思维的升级。
Prometheus + Grafana 这套组合的优势在于:生态成熟、接入成本低、扩展性强,既满足单节点爬虫的基础监控,也能支撑成百上千节点的分布式爬虫集群。建设过程不必追求一步到位,建议按 "基础指标接入→可视化仪表盘→核心告警→深度优化" 四步走,逐步迭代完善。
当你能在故障发生的第一分钟收到精准告警,并通过仪表盘在三分钟内定位根因时,这套监控体系就真正发挥了它的价值 ------ 它不是成本,而是对业务稳定性的长期投资。