日志监控与告警系统在爬虫运维中的实践:从ELK到自研轻量方案

简介: 针对中小爬虫系统“静默崩溃”痛点,本文提出轻量级监控方案:基于Redis实现结构化日志收集、关键指标(请求成功率/采集量)聚合、规则驱动告警(如成功率<80%自动钉钉通知),无需ELK,部署简单、响应及时。(239字)

一、业务背景
爬虫系统最怕的是无声无息地挂了——你不知道它什么时候停止工作了,等发现的时候已经几个小时没有新数据了。
我最早用ELK(Elasticsearch + Logstash + Kibana)做日志监控,但ELK太重了——三个组件都要部署和维护,对于中小规模的爬虫系统来说有点大材小用。
二、轻量级日志收集方案
我设计了一个更轻量的方案:
python
import loggingimport jsonimport redisimport timeclass StructuredLogger: """结构化日志记录器""" def init(self): self.redis = redis.Redis(decode_responses=True) self.log_key = "crawler:logs" def log(self, level, message, kwargs): log_entry = { 'timestamp': time.time(), 'level': level, 'message': message, kwargs } # 写入Redis List(最新的在最前面) self.redis.lpush(self.log_key, json.dumps(log_entry)) # 只保留最近10000条 self.redis.ltrim(self.log_key, 0, 9999) # 同时输出到控制台(开发环境) print(f"[{level}] {message}")# 使用logger = StructuredLogger()logger.log('INFO', '爬虫启动', spider='rakuten', worker_id=1)logger.log('ERROR', '请求失败', url='https://api.rakuten.co.jp', status_code=500)
三、关键指标监控
除了日志,还需要监控关键业务指标:
python
class MetricsCollector: def init(self): self.redis = redis.Redis(decode_responses=True) def record_request(self, platform, success=True): """记录请求""" key = f"metrics:requests:{platform}:{time.strftime('%Y%m%d%H')}" self.redis.hincrby(key, 'total', 1) if not success: self.redis.hincrby(key, 'failed', 1) self.redis.expire(key, 86400 7) # 保留7天 def record_item(self, platform, count=1): """记录采集到的商品数""" key = f"metrics:items:{platform}:{time.strftime('%Y%m%d%H')}" self.redis.hincrby(key, 'count', count) self.redis.expire(key, 86400 7) def get_recent_metrics(self, platform, hours=24): """获取最近N小时的指标""" metrics = [] for i in range(hours): hour = (time.time() - i 3600) hour_str = time.strftime('%Y%m%d%H', time.localtime(hour)) key = f"metrics:requests:{platform}:{hour_str}" data = self.redis.hgetall(key) if data: metrics.append({ 'hour': hour_str, 'total': int(data.get('total', 0)), 'failed': int(data.get('failed', 0)) }) return metrics
四、告警规则引擎
基于收集的指标,配置告警规则:
python
class AlertEngine: def init(self, metrics_collector): self.metrics = metrics_collector self.rules = [] self.alerted = {} # 记录已触发的告警,防止重复 def add_rule(self, rule): """添加告警规则""" self.rules.append(rule) def check(self): """定期检查所有规则""" for rule in self.rules: if self._evaluate_rule(rule): self._send_alert(rule) def _evaluate_rule(self, rule): """评估规则是否触发""" # 规则示例:{"platform": "rakuten", "metric": "success_rate", "threshold": 0.8, "window": 60} metrics = self.metrics.get_recent_metrics( rule['platform'], hours=rule.get('window', 1) ) total = sum(m['total'] for m in metrics) failed = sum(m['failed'] for m in metrics) if total == 0: # 没有请求,可能爬虫已停止 return rule.get('alert_on_zero', False) success_rate = (total - failed) / total return success_rate < rule['threshold']
五、告警通知
python
class AlertNotifier: def init(self): self.webhook_url = os.getenv('DINGTALK_WEBHOOK') def send(self, rule, metrics): message = f""" 【爬虫告警】 平台: {rule['platform']} 规则: {rule['description']} 当前成功率: {metrics['success_rate']:.2%} 阈值: {rule['threshold']:.2%} 时间: {time.strftime('%Y-%m-%d %H:%M:%S')} """ # 发送到钉钉/飞书/企业微信 requests.post(self.webhook_url, json={'text': message})
六、总结
轻量级监控方案的核心是:结构化日志 + 关键指标 + 告警规则。这套方案不需要部署ELK这样重量的组件,用Redis就能搞定,适合中小规模的爬虫系统。
第17篇
RabbitMQ在分布式订单系统中的三种交换器使用场景
一、业务背景
在跨境电商订单系统中,不同模块之间需要异步通信。RabbitMQ提供了四种交换器(Exchange)类型,每种适用于不同的场景。
二、Direct Exchange:精准路由
Direct Exchange根据Routing Key精确匹配队列。
python
import pikaclass DirectExchangeExample: def init(self): self.connection = pika.BlockingConnection( pika.ConnectionParameters('localhost') ) self.channel = self.connection.channel() # 声明Direct Exchange self.channel.exchange_declare( exchange='order_direct', exchange_type='direct' ) def setup_queues(self): # 不同优先级的订单走不同队列 self.channel.queue_declare('order_high_priority') self.channel.queue_declare('order_normal_priority') self.channel.queue_declare('order_low_priority') # 绑定 self.channel.queue_bind( exchange='order_direct', queue='order_high_priority', routing_key='high' ) self.channel.queue_bind( exchange='order_direct', queue='order_normal_priority', routing_key='normal' ) self.channel.queue_bind( exchange='order_direct', queue='order_low_priority', routing_key='low' ) def publish_order(self, order, priority='normal'): self.channel.basic_publish( exchange='order_direct', routing_key=priority, body=json.dumps(order) )
使用场景:不同优先级的订单(VIP用户、普通用户、批量订单)分开处理。
三、Topic Exchange:模糊匹配
Topic Exchange根据通配符匹配Routing Key。
python
class TopicExchangeExample: def init(self): self.channel.exchange_declare( exchange='order_topic', exchange_type='topic' ) def setup_queues(self): # 日本订单队列 self.channel.queue_declare('order_jp') self.channel.queue_bind( exchange='order_topic', queue='order_jp', routing_key='order.jp.
' ) # 美国订单队列 self.channel.queue_declare('order_us') self.channel.queue_bind( exchange='order_topic', queue='order_us', routing_key='order.us.*' ) # 所有订单的日志队列 self.channel.queue_declare('order_log') self.channel.queue_bind( exchange='order_topic', queue='order_log', routing_key='order.#' # #匹配任意多个词 )
使用场景:按地域(国家、地区)路由订单,同时有一个全局日志队列。
四、Fanout Exchange:广播
Fanout Exchange把消息广播给所有绑定的队列。
python
class FanoutExchangeExample: def init(self): self.channel.exchange_declare( exchange='order_fanout', exchange_type='fanout' ) def setup_queues(self): # 所有消费者都收到同样的消息 self.channel.queue_declare('order_storage') # 存储服务 self.channel.queue_declare('order_notify') # 通知服务 self.channel.queue_declare('order_analytics') # 分析服务 self.channel.queue_bind('order_storage', 'order_fanout') self.channel.queue_bind('order_notify', 'order_fanout') self.channel.queue_bind('order_analytics', 'order_fanout') def publish_order(self, order): # 所有绑定的队列都会收到 self.channel.basic_publish( exchange='order_fanout', routing_key='', # Fanout忽略routing_key body=json.dumps(order) )
使用场景:订单状态变更需要通知多个服务(存储、通知、分析、日志)。
五、Headers Exchange:复杂条件匹配
Headers Exchange根据消息头中的键值对匹配,支持更复杂的条件。
python
class HeadersExchangeExample: def init(self): self.channel.exchange_declare( exchange='order_headers', exchange_type='headers' ) def setup_queues(self): # 大额订单队列 self.channel.queue_declare('order_large') self.channel.queue_bind( exchange='order_headers', queue='order_large', arguments={ 'x-match': 'all', # 所有条件都满足 'amount': 'large', 'status': 'paid' } ) # 紧急订单队列 self.channel.queue_declare('order_urgent') self.channel.queue_bind( exchange='order_headers', queue='order_urgent', arguments={ 'x-match': 'any', # 任一条件满足 'urgent': 'true', 'priority': 'high' } )
六、总结
四种交换器的选择原则:Direct用于精准路由、Topic用于模糊匹配、Fanout用于广播、Headers用于复杂条件。在跨境电商订单系统中,Direct用得最多(按订单类型路由),Fanout用于状态广播。

目录
相关文章
|
6天前
|
缓存 人工智能 安全
GPT-5.6 Terra与GPT-5.5性能实测:成本减半后的跑分对比与快速迁移指南
GPT-5.6 Terra 的定价为每百万 token 输入 2.50/输出 15。GPT-5.5 则是 5/ 30。Terra 的每一项费率,包括 $0.25/M 的缓存读取,都恰好是 GPT-5.5 的一半,因此在任何工作负载组合下,Terra 都固定 便宜 2.0x。以每天 10 万次请求、3K token 提示词计算,大约是 Terra 每天 2,000,GPT−5.5每天 4,000,即每月约 60,000对 120,000。问题在于:OpenAI 没有发布任何针对 Terra 的编码基准。那个著名的 91.9% Terminal-Bench 数字是 Sol 在 Ul
|
1天前
|
数据采集 机器学习/深度学习 人工智能
田间杂草定位与检测4200张YOLO智慧农业数据集分享
本数据集含4200张真实农田图像,YOLO格式,单类别(杂草)高质量标注,覆盖多作物、多光照、多生长阶段等复杂场景,专为智慧农业杂草检测与智能除草设备研发设计,支持YOLOv5/v8/v10等主流模型训练。
326 93
|
2天前
|
缓存 UED 开发者
Codex109天重置23次,明天还要再送一次
Codex近109天完成23次额度重置,7月14日将迎来第24次。Tibo高频响应用户反馈:优化GPT-5.6高消耗问题、补发失效福利、调整重置时间——形成“反馈→回应→修复→补偿”正向闭环,彰显以用户为中心的产品哲学。(239字)
488 11
|
6天前
|
人工智能 缓存 JSON
刚刚 GPT-5.6 发布,吊打 Claude 5 和 Grok 4.5?一手实测来啦!
GPT-5.6 刚发布,跑分号称超越 Fable 5,真的假的?附一手实测,让 3 个最强 AI 编程模型 GPT-5.6 Sol、Claude Fable 5、Grok 4.5 在 Cursor 里同时一把梭开发网页游戏,看看最新模型到底谁更能打。
332 0
|
6天前
|
存储 人工智能 JSON
Qwen 本地部署搭配 ComfyUI 生成 AI 漫剧完整实操指南(小白零基础可落地,零成本无限生成+角色一致性天花板)
2026全网最优本地漫剧流水线:零成本、离线运行、角色统一、低配(8G显卡)可跑。融合Qwen本地大模型+ComfyUI双引擎,实现剧本生成→分镜绘图→动态成片全自动,隐私安全、无审核限流,新手30分钟上手,日更无忧。(239字)