本文目录导读:

针对Python脚本告警同步任务性能异常,我推荐以下几种实现方案:
基础指标采集方案
import time
import threading
from datetime import datetime, timedelta
import smtplib
import json
from email.mime.text import MIMEText
from typing import Dict, List
class SyncTaskMonitor:
def __init__(self, config: dict):
self.config = config
self.metrics = {
'processing_time': [], # 处理时间记录
'batch_size': [], # 批处理大小
'error_count': 0, # 错误计数
'success_count': 0, # 成功计数
'last_execution_time': None,
'throughput': [] # 吞吐量记录
}
self.thresholds = config.get('thresholds', {
'max_processing_time': 30, # 最大处理时间(秒)
'min_batch_size': 100, # 最小批处理大小
'max_error_rate': 0.05, # 最大错误率
'throughput_window': 300 # 吞吐量统计窗口(5分钟)
})
def record_execution(self, execution_time: float, batch_size: int, errors: int):
"""记录执行指标"""
self.metrics['processing_time'].append({
'time': datetime.now(),
'value': execution_time
})
self.metrics['batch_size'].append({
'time': datetime.now(),
'value': batch_size
})
self.metrics['error_count'] += errors
self.metrics['success_count'] += batch_size
self.metrics['last_execution_time'] = datetime.now()
# 计算吞吐量
throughput = batch_size / execution_time if execution_time > 0 else 0
self.metrics['throughput'].append({
'time': datetime.now(),
'value': throughput
})
# 清理旧数据
self._clean_old_metrics()
def _clean_old_metrics(self, retention_minutes: int = 60):
"""清理超过保留时间的指标数据"""
cutoff_time = datetime.now() - timedelta(minutes=retention_minutes)
for key in self.metrics:
if isinstance(self.metrics[key], list):
self.metrics[key] = [
item for item in self.metrics[key]
if item['time'] > cutoff_time
]
异常检测与告警逻辑
class PerformanceAlert:
def __init__(self, notifiers: list):
self.notifiers = notifiers # 告警通知器列表
def check_performance_anomalies(self, monitor: 'SyncTaskMonitor') -> list:
"""检查性能异常"""
alerts = []
# 1. 检测处理时间异常(滑动窗口)
recent_times = [p['value'] for p in monitor.metrics['processing_time'][-10:]]
if recent_times:
avg_time = sum(recent_times) / len(recent_times)
if avg_time > monitor.thresholds['max_processing_time']:
alerts.append({
'type': 'processing_time_high',
'severity': 'warning',
'message': f'平均处理时间 {avg_time:.2f}s 超过阈值 {monitor.thresholds["max_processing_time"]}s',
'timestamp': datetime.now()
})
# 2. 检测批处理大小异常
recent_batches = [b['value'] for b in monitor.metrics['batch_size'][-5:]]
if recent_batches:
avg_batch = sum(recent_batches) / len(recent_batches)
if avg_batch < monitor.thresholds['min_batch_size']:
alerts.append({
'type': 'batch_size_low',
'severity': 'warning',
'message': f'平均批处理大小 {avg_batch:.0f} 低于阈值 {monitor.thresholds["min_batch_size"]}',
'timestamp': datetime.now()
})
# 3. 检测错误率异常
total_ops = monitor.metrics['success_count'] + monitor.metrics['error_count']
if total_ops > 0:
error_rate = monitor.metrics['error_count'] / total_ops
if error_rate > monitor.thresholds['max_error_rate']:
alerts.append({
'type': 'error_rate_high',
'severity': 'critical',
'message': f'错误率 {error_rate:.2%} 超过阈值 {monitor.thresholds["max_error_rate"]:.0%}',
'timestamp': datetime.now()
})
# 4. 检测吞吐量下降
throughput_window = monitor.thresholds['throughput_window']
recent_throughput = [
t['value'] for t in monitor.metrics['throughput']
if t['time'] > datetime.now() - timedelta(seconds=throughput_window)
]
if len(recent_throughput) >= 2:
current_avg = sum(recent_throughput[-3:]) / min(len(recent_throughput[-3:]), 3)
historical_avg = sum(recent_throughput[:-3]) / max(len(recent_throughput[:-3]), 1)
if historical_avg > 0 and current_avg / historical_avg < 0.7:
alerts.append({
'type': 'throughput_decrease',
'severity': 'warning',
'message': f'吞吐量下降30%,当前: {current_avg:.2f} 条/秒, 历史: {historical_avg:.2f} 条/秒',
'timestamp': datetime.now()
})
return alerts
def send_alerts(self, alerts: list):
"""发送告警通知"""
for alert in alerts:
for notifier in self.notifiers:
try:
notifier.send(alert)
except Exception as e:
print(f"发送告警失败: {e}")
告警通知器实现
import requests
import logging
from abc import ABC, abstractmethod
class BaseNotifier(ABC):
@abstractmethod
def send(self, alert: dict):
pass
class EmailNotifier(BaseNotifier):
def __init__(self, smtp_config: dict):
self.smtp_config = smtp_config
def send(self, alert: dict):
msg = MIMEText(
f"告警类型: {alert['type']}\n"
f"告警级别: {alert['severity']}\n"
f"告警时间: {alert['timestamp']}\n"
f"告警内容: {alert['message']}"
)
msg['Subject'] = f"[告警] 同步任务性能异常 - {alert['severity']}"
msg['From'] = self.smtp_config['from']
msg['To'] = ','.join(self.smtp_config['to'])
with smtplib.SMTP(self.smtp_config['host'], self.smtp_config['port']) as server:
server.starttls()
server.login(self.smtp_config['user'], self.smtp_config['password'])
server.send_message(msg)
class WebhookNotifier(BaseNotifier):
def __init__(self, webhook_url: str):
self.webhook_url = webhook_url
def send(self, alert: dict):
payload = {
'msgtype': 'text',
'text': {
'content': f"【同步任务告警】\n级别: {alert['severity']}\n内容: {alert['message']}"
}
}
requests.post(self.webhook_url, json=payload)
class LogNotifier(BaseNotifier):
def __init__(self, logger: logging.Logger):
self.logger = logger
def send(self, alert: dict):
log_method = getattr(self.logger, alert['severity'].lower(), self.logger.warning)
log_method(f"{alert['type']}: {alert['message']}")
集成使用示例
import logging
def sync_task_worker(monitor, alert_manager):
"""同步任务工作线程"""
while True:
try:
start_time = time.time()
# 执行同步任务
batch_size, errors = execute_sync_batch()
execution_time = time.time() - start_time
monitor.record_execution(execution_time, batch_size, errors)
# 检查性能异常
alerts = alert_manager.check_performance_anomalies(monitor)
if alerts:
alert_manager.send_alerts(alerts)
except Exception as e:
logging.error(f"同步任务执行异常: {e}")
# 发送任务异常告警
alert_manager.send_alerts([{
'type': 'task_exception',
'severity': 'critical',
'message': f'同步任务执行异常: {str(e)}',
'timestamp': datetime.now()
}])
def execute_sync_batch():
"""执行同步批次(示例)"""
# 实际业务逻辑
import random
time.sleep(random.uniform(1, 5))
batch_size = random.randint(50, 200)
errors = int(batch_size * random.uniform(0, 0.1))
return batch_size, errors
if __name__ == "__main__":
# 配置
config = {
'thresholds': {
'max_processing_time': 30,
'min_batch_size': 100,
'max_error_rate': 0.05,
'throughput_window': 300
}
}
# 初始化
monitor = SyncTaskMonitor(config)
logger = logging.getLogger('sync_task')
# 创建告警管理器(支持多个通知方式)
alert_manager = PerformanceAlert([
LogNotifier(logger),
EmailNotifier({
'host': 'smtp.example.com',
'port': 587,
'user': 'user@example.com',
'password': 'password',
'from': 'monitor@example.com',
'to': ['admin@example.com']
}),
WebhookNotifier('https://hooks.example.com/webhook')
])
# 启动监控线程
monitor_thread = threading.Thread(
target=sync_task_worker,
args=(monitor, alert_manager),
daemon=True
)
monitor_thread.start()
# 保持主线程运行
monitor_thread.join()
高级告警策略
class AdvancedAlertStrategy:
"""高级告警策略"""
def __init__(self):
self.alert_history = []
self.cooldown_period = 300 # 5分钟冷却期
self.escalation_threshold = 3 # 连续告警升级阈值
def should_alert(self, alert: dict) -> bool:
"""判断是否需要发送告警(防重复告警)"""
current_time = datetime.now()
# 检查冷却期
recent_alerts = [a for a in self.alert_history
if a['timestamp'] > current_time - timedelta(seconds=self.cooldown_period)
and a['type'] == alert['type']]
if recent_alerts:
# 检查是否有相同类型的告警在冷却期内
return False
# 记录告警
self.alert_history.append(alert)
# 检查是否需要升级(连续相同告警)
similar_alerts = [a for a in self.alert_history
if a['type'] == alert['type']
and a['timestamp'] > current_time - timedelta(hours=1)]
if len(similar_alerts) >= self.escalation_threshold:
alert['severity'] = self._escalate_severity(alert['severity'])
return True
def _escalate_severity(self, severity: str) -> str:
"""升级告警级别"""
escalation_map = {
'info': 'warning',
'warning': 'error',
'error': 'critical'
}
return escalation_map.get(severity, 'critical')
部署建议
- 数据存储: 使用时序数据库(如InfluxDB)存储指标数据
- 可视化: 集成Grafana展示性能趋势
- 告警聚合: 使用AlertManager处理告警风暴
- 分布式监控: 对大规模部署使用Prometheus采集指标
这个方案可以根据实际需求调整阈值和告警策略,并支持多种通知方式。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播