问题场景还原
最近在维护一个遗留的Progress数据库系统时遇到典型的生产环境问题:
ssh user@production-server
./start_progress.sh # 内部会启动数据库进程
# 网络闪断导致SSH连接中断 → 整个进程树被杀死
为什么常规方案失效
经过测试发现以下方法不适用:
- 终端复用器方案:tmux/screen因TERM=at386的特殊要求无法使用
- 后台运行方案:nohup/disown在父子进程存在IPC通信时失效
终极解决方案:系统级守护
推荐使用systemd创建用户级服务单元:
# /etc/systemd/system/progress.service
[Unit]
Description=Progress Database Daemon
After=network.target
[Service]
User=dbadmin
WorkingDirectory=/opt/progress
ExecStart=/bin/bash /opt/progress/start_progress.sh
Restart=always
KillSignal=SIGTERM
TimeoutStopSec=30
[Install]
WantedBy=multi-user.target
关键配置说明
参数 | 作用 |
---|---|
Restart=always | 异常退出时自动重启 |
KillSignal | 避免SIGHUP信号 |
TimeoutStopSec | 优雅停止超时 |
替代方案:进程级防护
如果无法使用systemd,可以改造启动脚本:
#!/bin/bash
# 使用Linux进程组隔离
{
setsid ./progress_db \
--config /etc/progress.cfg \
>> /var/log/progress.log 2>&1
} &
验证手段
测试SSH断开后的进程存活:
# 查看进程树
pstree -alp $(pgrep progress)
# 检查系统日志
journalctl -u progress -f