本文目录导读:

我来介绍几种常见的进程守护脚本写法,适用于不同场景。
Shell 脚本守护(Linux/Unix)
基础守护脚本
#!/bin/bash
# 进程守护脚本
PROCESS_NAME="your_app"
PROCESS_PATH="/usr/local/bin/your_app"
LOG_FILE="/var/log/process_monitor.log"
while true; do
# 检查进程是否在运行
if ! pgrep -f "$PROCESS_NAME" > /dev/null; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - $PROCESS_NAME 未运行,正在重启..." >> $LOG_FILE
# 启动进程
$PROCESS_PATH >> $LOG_FILE 2>&1 &
echo "$(date '+%Y-%m-%d %H:%M:%S') - $PROCESS_NAME 已重启" >> $LOG_FILE
fi
# 每10秒检查一次
sleep 10
done
带PID文件的守护脚本
#!/bin/bash
# 定义进程信息
APP_NAME="myapp"
APP_PATH="/opt/myapp/myapp.sh"
PID_FILE="/var/run/${APP_NAME}.pid"
LOG_FILE="/var/log/${APP_NAME}_monitor.log"
start_app() {
nohup $APP_PATH > /dev/null 2>&1 &
echo $! > $PID_FILE
echo "$(date '+%Y-%m-%d %H:%M:%S') - PID: $! 已启动" >> $LOG_FILE
}
stop_app() {
if [ -f $PID_FILE ]; then
pid=$(cat $PID_FILE)
kill -9 $pid 2>/dev/null
rm -f $PID_FILE
echo "$(date '+%Y-%m-%d %H:%M:%S') - 已停止" >> $LOG_FILE
fi
}
check_app() {
if [ -f $PID_FILE ]; then
pid=$(cat $PID_FILE)
if kill -0 $pid 2>/dev/null; then
return 0 # 运行中
else
rm -f $PID_FILE
return 1 # 未运行
fi
else
return 1
fi
}
# 主循环
while true; do
if ! check_app; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - 检测到进程未运行,重启中..." >> $LOG_FILE
start_app
fi
sleep 30
done
Python 守护脚本
简单版
#!/usr/bin/env python3
import subprocess
import time
import sys
import logging
logging.basicConfig(
filename='/var/log/app_monitor.log',
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
PROCESS_CMD = ["python", "my_app.py"] # 要守护的进程命令
def check_process(proc):
"""检查进程是否存活"""
return proc.poll() is None
def start_process():
"""启动新进程"""
proc = subprocess.Popen(
PROCESS_CMD,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True
)
logging.info(f"进程启动,PID: {proc.pid}")
return proc
def main():
# 启动初始进程
proc = start_process()
while True:
if not check_process(proc):
logging.warning(f"PID {proc.pid} 已退出,退出码: {proc.returncode}")
proc = start_process()
# 每5秒检查一次
time.sleep(5)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\n监控脚本被终止")
sys.exit(0)
高级版(带负载均衡和重启限制)
#!/usr/bin/env python3
import subprocess
import time
import logging
import signal
import sys
from datetime import datetime, timedelta
class ProcessGuard:
def __init__(self, command, check_interval=5, max_restarts=10, window=300):
self.command = command
self.check_interval = check_interval
self.max_restarts = max_restarts
self.window = window
self.process = None
self.restart_history = []
logging.basicConfig(
filename='process_guard.log',
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
signal.signal(signal.SIGINT, self.signal_handler)
signal.signal(signal.SIGTERM, self.signal_handler)
def signal_handler(self, sig, frame):
"""处理退出信号"""
logging.info(f"收到信号 {sig},停止守护进程")
if self.process:
self.process.terminate()
sys.exit(0)
def can_restart(self):
"""检查是否超过重启限制"""
if not self.restart_history:
return True
# 清理过期记录
now = time.time()
self.restart_history = [t for t in self.restart_history
if now - t < self.window]
return len(self.restart_history) < self.max_restarts
def start_process(self):
"""启动受保护进程"""
try:
self.process = subprocess.Popen(
self.command,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT
)
logging.info(f"进程启动,PID: {self.process.pid}")
return True
except Exception as e:
logging.error(f"进程启动失败: {e}")
return False
def monitor(self):
"""监控进程"""
if not self.start_process():
logging.error("初始进程启动失败")
return
while True:
time.sleep(self.check_interval)
if self.process.poll() is not None:
if self.can_restart():
self.restart_history.append(time.time())
logging.warning(f"进程异常退出(退出码: {self.process.returncode}),正在重启...")
self.start_process()
else:
logging.error("重启次数过多,暂停重启")
break
# 使用示例
if __name__ == "__main__":
guard = ProcessGuard(
command="python my_app.py",
check_interval=10,
max_restarts=5,
window=300
)
guard.monitor()
Systemd 服务守护(推荐生产环境)
创建 /etc/systemd/system/myapp.service:
[Unit] Description=My Application Service After=network.target [Service] Type=simple User=your_user WorkingDirectory=/path/to/app ExecStart=/usr/bin/python3 /path/to/app/my_app.py Restart=always RestartSec=10 # 每次重启前等待时间 # 优雅停止 TimeoutStopSec=30 KillSignal=SIGTERM # 资源限制 MemoryMax=1G CPUQuota=50% [Install] WantedBy=multi-user.target
启用服务:
sudo systemctl daemon-reload sudo systemctl enable myapp.service sudo systemctl start myapp.service # 查看状态 sudo systemctl status myapp.service
Docker/容器守护
Docker Compose 文件
version: '3.8'
services:
myapp:
image: myapp:latest
restart: always # 容器退出时自动重启
environment:
- TZ=Asia/Shanghai
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 60s
timeout: 5s
retries: 3
start_period: 30s
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
选择建议
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 生产环境 | Systemd | 原生支持、可靠、配置灵活 |
| Linux 简单任务 | Shell 脚本 | 轻量、易修改 |
| 复杂逻辑 | Python 脚本 | 可编程、可扩展 |
| 容器环境 | Docker restart | 简单、容器生态支持 |
| 分布式系统 | Kubernetes | 自动扩缩容、自愈 |
最佳实践建议:
- 日志管理:保留进程日志,方便排查
- 优雅停止:支持 SIGTERM,让进程有时间保存状态
- 启动限制:防止进程崩溃循环重启
- 监控告警:重启次数过多时发送告警
- 资源限制:防止进程占用过多内存/CPU
- 健康检查:不只是检查进程存活,还要检查业务健康
根据你的具体需求选择合适的方案即可。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播