本文目录导读:

我来提供一个完整的服务自动修复脚本实现方案,包含多种实现方式:
基础版 - Shell脚本实现
#!/bin/bash
# 服务自动修复脚本 - 基础版
# 文件名: service_auto_repair.sh
# 配置
SERVICE_NAME="your-service-name"
LOG_FILE="/var/log/service_self_repair.log"
MAX_RETRIES=3
RETRY_INTERVAL=5 # 秒
# 日志函数
log_message() {
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] $1" | tee -a $LOG_FILE
}
# 健康检查函数
check_service_health() {
# 方法1:检查进程是否在运行
if pgrep -x "$SERVICE_NAME" > /dev/null 2>&1; then
return 0
fi
# 方法2:通过systemd检查
if systemctl is-active --quiet "$SERVICE_NAME" 2>/dev/null; then
return 0
fi
# 方法3:通过curl检查HTTP服务
if curl -f http://localhost:8080/health > /dev/null 2>&1; then
return 0
fi
return 1
}
# 修复服务函数
repair_service() {
local attempt=$1
log_message "开始第 $attempt 次修复尝试..."
# 停止服务
systemctl stop "$SERVICE_NAME" 2>/dev/null || killall "$SERVICE_NAME" 2>/dev/null
sleep 2
# 清理状态
rm -f /var/run/"$SERVICE_NAME".pid 2>/dev/null
# 启动服务
systemctl start "$SERVICE_NAME" 2>/dev/null || {
# 备用启动方式
/usr/bin/$SERVICE_NAME &
}
sleep $RETRY_INTERVAL
# 验证服务是否正常运行
if check_service_health; then
log_message "第 $attempt 次修复成功!"
return 0
fi
return 1
}
# 主修复流程
main() {
log_message "服务修复脚本启动 - 检查: $SERVICE_NAME"
# 检查服务是否正常运行
if check_service_health; then
log_message "服务正常运行,无需修复"
exit 0
fi
log_message "服务异常,开始修复..."
# 重试修复
for ((i=1; i<=MAX_RETRIES; i++)); do
if repair_service $i; then
exit 0
fi
if [ $i -lt $MAX_RETRIES ]; then
log_message "等待 $RETRY_INTERVAL 秒后重试..."
sleep $RETRY_INTERVAL
fi
done
# 所有重试都失败
log_message "修复失败!开始深度修复..."
deep_repair_service
}
# 深度修复
deep_repair_service() {
log_message "执行深度修复方案..."
# 重启依赖服务
systemctl restart network 2>/dev/null
systemctl restart mysql 2>/dev/null
# 清理日志和缓存
journalctl --vacuum-time=1d 2>/dev/null
sync && echo 3 > /proc/sys/vm/drop_caches 2>/dev/null
# 重新安装服务(示例)
# yum reinstall -y $SERVICE_NAME 2>/dev/null
# 最后尝试重启
systemctl restart "$SERVICE_NAME"
if check_service_health; then
log_message "深度修复成功!"
else
log_message "深度修复失败,需要人工介入"
send_alert "服务 $SERVICE_NAME 修复失败"
fi
}
# 告警函数
send_alert() {
local message="$1"
# 发送邮件告警
echo "$message" | mail -s "[ALERT] 服务修复失败" admin@example.com
# 发送Slack通知
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"$message\"}" \
https://hooks.slack.com/services/YOUR/WEBHOOK/URL
}
# 设置crontab定时任务
setup_cron() {
local cron_job="*/5 * * * * /path/to/$0"
(crontab -l 2>/dev/null | grep -v "$0"; echo "$cron_job") | crontab -
log_message "已添加定时任务:每5分钟执行一次"
}
# 执行主函数
main "$@"
Python版本 - 功能更强大
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
服务自动修复脚本 - Python版本
文件名: service_auto_repair.py
"""
import os
import sys
import time
import logging
import subprocess
from datetime import datetime
import requests
import json
import smtplib
from email.mime.text import MIMEText
import argparse
class ServiceAutoRepair:
"""服务自动修复类"""
def __init__(self, service_name, config_file=None):
self.service_name = service_name
self.max_retries = 3
self.retry_interval = 5
self.log_file = "/var/log/service_self_repair.log"
self.setup_logging()
# 配置邮箱告警
self.email_config = {
'smtp_server': 'smtp.gmail.com',
'smtp_port': 587,
'username': 'your-email@gmail.com',
'password': 'your-password',
'to_email': 'admin@example.com'
}
# 配置Slack告警
self.slack_webhook_url = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
def setup_logging(self):
"""设置日志"""
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler(self.log_file),
logging.StreamHandler()
]
)
self.logger = logging.getLogger(__name__)
def check_health(self):
"""检查服务健康状态"""
try:
# 方法1:systemd检查
result = subprocess.run(
['systemctl', 'is-active', '--quiet', self.service_name],
capture_output=True
)
if result.returncode == 0:
return True
# 方法2:进程检查
result = subprocess.run(
['pgrep', '-x', self.service_name],
capture_output=True
)
if result.returncode == 0:
return True
# 方法3:HTTP检查
try:
response = requests.get(
'http://localhost:8080/health',
timeout=5
)
if response.status_code == 200:
return True
except:
pass
except Exception as e:
self.logger.error(f"健康检查失败: {str(e)}")
return False
def repair_service(self, attempt):
"""修复服务"""
self.logger.info(f"开始第 {attempt} 次修复尝试...")
try:
# 停止服务
subprocess.run(['systemctl', 'stop', self.service_name],
capture_output=True, check=False)
time.sleep(2)
# 清理PID文件
pid_file = f"/var/run/{self.service_name}.pid"
if os.path.exists(pid_file):
os.remove(pid_file)
# 启动服务
subprocess.run(['systemctl', 'start', self.service_name],
capture_output=True, check=False)
time.sleep(self.retry_interval)
if self.check_health():
self.logger.info(f"第 {attempt} 次修复成功!")
return True
except Exception as e:
self.logger.error(f"修复失败: {str(e)}")
return False
def deep_repair(self):
"""深度修复"""
self.logger.info("执行深度修复...")
try:
# 重启依赖服务
for dep_service in ['network', 'mysql', 'nginx']:
subprocess.run(['systemctl', 'restart', dep_service],
capture_output=True, check=False)
# 清理缓存
with open('/proc/sys/vm/drop_caches', 'w') as f:
f.write('3')
# 清理日志
subprocess.run(['journalctl', '--vacuum-time=1d'],
capture_output=True, check=False)
# 重新启动服务
subprocess.run(['systemctl', 'restart', self.service_name],
capture_output=True, check=False)
time.sleep(5)
if self.check_health():
self.logger.info("深度修复成功!")
return True
except Exception as e:
self.logger.error(f"深度修复失败: {str(e)}")
return False
def send_alert(self, message):
"""发送告警通知"""
self.logger.warning(f"发送告警: {message}")
# 发送邮件
try:
msg = MIMEText(message)
msg['Subject'] = f'[ALERT] 服务修复失败 - {self.service_name}'
msg['From'] = self.email_config['username']
msg['To'] = self.email_config['to_email']
with smtplib.SMTP(
self.email_config['smtp_server'],
self.email_config['smtp_port']
) as server:
server.starttls()
server.login(
self.email_config['username'],
self.email_config['password']
)
server.send_message(msg)
except Exception as e:
self.logger.error(f"发送邮件失败: {str(e)}")
# 发送Slack通知
try:
requests.post(
self.slack_webhook_url,
json={'text': message},
timeout=5
)
except Exception as e:
self.logger.error(f"发送Slack通知失败: {str(e)}")
def run(self):
"""主修复流程"""
self.logger.info(f"服务修复脚本启动 - 检查: {self.service_name}")
# 检查服务是否正常运行
if self.check_health():
self.logger.info("服务正常运行,无需修复")
return True
self.logger.info("服务异常,开始修复...")
# 重试修复
for attempt in range(1, self.max_retries + 1):
if self.repair_service(attempt):
return True
if attempt < self.max_retries:
self.logger.info(f"等待 {self.retry_interval} 秒后重试...")
time.sleep(self.retry_interval)
# 所有重试都失败
self.logger.error("标准修复失败,尝试深度修复...")
if self.deep_repair():
return True
# 完全失败
error_msg = f"服务 {self.service_name} 自动修复失败,需要人工介入"
self.logger.error(error_msg)
self.send_alert(error_msg)
return False
def add_cron_job(self, interval=5):
"""添加定时任务"""
script_path = os.path.abspath(__file__)
cron_job = f"*/{interval} * * * * /usr/bin/python3 {script_path} --service {self.service_name}"
# 获取当前crontab
result = subprocess.run(['crontab', '-l'], capture_output=True, text=True)
current_cron = result.stdout
# 移除旧的定时任务
new_cron = "\n".join(
[line for line in current_cron.split('\n')
if self.service_name not in line]
)
# 添加新任务
if new_cron:
new_cron += "\n" + cron_job
else:
new_cron = cron_job
# 写入crontab
with subprocess.Popen(['crontab'], stdin=subprocess.PIPE) as proc:
proc.communicate(new_cron.encode())
self.logger.info(f"已添加定时任务:每{interval}分钟执行一次")
def generate_report(self):
"""生成修复报告"""
report = {
'timestamp': datetime.now().isoformat(),
'service': self.service_name,
'status': 'healthy' if self.check_health() else 'unhealthy',
'repair_attempts': self.max_retries,
'last_check': datetime.now().isoformat()
}
# 保存报告到文件
report_file = f"/var/log/{self.service_name}_repair_report.json"
with open(report_file, 'w') as f:
json.dump(report, f, indent=2)
self.logger.info(f"报告已保存到: {report_file}")
return report
def main():
"""主函数"""
parser = argparse.ArgumentParser(description='服务自动修复脚本')
parser.add_argument('--service', required=True, help='服务名称')
parser.add_argument('--setup-cron', action='store_true', help='设置定时任务')
parser.add_argument('--interval', type=int, default=5, help='检查间隔(分钟)')
args = parser.parse_args()
repair = ServiceAutoRepair(args.service)
if args.setup_cron:
repair.add_cron_job(args.interval)
else:
repair.run()
repair.generate_report()
if __name__ == '__main__':
main()
高级实现 - 使用Docker健康检查
# docker-compose.yml
version: '3.8'
services:
app:
image: your-app:latest
container_name: your-app
restart: always
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
environment:
- AUTO_REPAIR=true
volumes:
- ./repair.sh:/usr/local/bin/repair.sh
# Docker容器内的修复脚本
#!/bin/bash
while true; do
# 检查健康状态
if ! curl -f http://localhost:8080/health; then
echo "Service unhealthy, attempting repair..."
# 清理和重启
rm -rf /tmp/cache/*
kill -HUP 1 # 向init进程发送SIGHUP
# 记录日志
logger "Service auto-repair triggered"
fi
sleep 60
done
Kubernetes实现 - 使用Liveness探针
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: your-app:latest
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 5"]
使用指南
安装和配置
# 1. 下载脚本 curl -O https://your-server.com/service_auto_repair.sh chmod +x service_auto_repair.sh # 2. 配置服务 SERVICE_NAME="nginx" MAX_RETRIES=5 RETRY_INTERVAL=10 # 3. 设置定时任务 ./service_auto_repair.sh --setup-cron # 或手动添加crontab crontab -e */5 * * * * /path/to/service_auto_repair.sh --service nginx # 4. 日志查看 tail -f /var/log/service_self_repair.log # 5. 测试 ./service_auto_repair.sh --dry-run
最佳实践
-
完善健康检查:
- 实现自定义的健康检查端点
- 检查数据库连接
- 验证缓存状态
- 监控资源使用情况
-
分级修复策略:
- 第1级:重启服务
- 第2级:清理缓存和临时文件
- 第3级:重启依赖服务
- 第4级:重新部署
-
告警机制:
- 邮件通知
- Slack/企业微信
- PagerDuty集成
- 短信告警
-
日志和监控:
- 详细日志记录
- Prometheus指标导出
- Grafana仪表板
-
安全考虑:
- 限制脚本权限
- 使用非root用户运行
- 加密敏感信息
这个解决方案提供了从简单到复杂的多种实现方式,可以根据实际需求选择适合的方案。