0%

进程守护

持久化的python服务

进程守护指的是让一个程序在后台持续运行具有自我恢复能力(崩溃自动重启),随系统启动自动启动,并可通过命令进行控制。

1. linux下systemd 持久守护 Python 程序

创建systemd服务配置文件:

1
sudo nano /etc/systemd/system/myscript.service

内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Unit]
Description=My Persistent Python Script
After=network.target

[Service]
ExecStart=/usr/bin/python3 /home/user/run_my_job.py
WorkingDirectory=/home/user
Restart=always
RestartSec=5
User=your_linux_username
StandardOutput=append:/var/log/myscript.log
StandardError=append:/var/log/myscript.err
Environment=PYTHONUNBUFFERED=1

[Install]
WantedBy=multi-user.target

启用并启动服务:

1
2
3
4
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl enable myscript.service
sudo systemctl start myscript.service

查看日志和状态:

1
2
sudo systemctl status myscript.service
sudo tail -f /var/log/myscript.log

通过命令进行控制:

1
2
3
sudo systemctl stop myscript.service
sudo systemctl restart myscript.service
sudo systemctl disable myscript.service

2. 跨平台python进程管理工具supervisord

supervisord 是一个用 Python 编写的进程管理工具, 它可以监控、启动、停止、重启你python脚本在内的进程。可以直接利用pip下载:

1
pip install supervisor

Supervisor 由两个核心组件组成:

  • supervisord守护进程:负责读取配置、启动/监控任务
  • supervisorctl命令行客户端:用于查看状态、重启任务等

使用时,首先生成一个默认的配置:

1
echo_supervisord_conf > supervisord.conf

将需要守护的进程添加到配置文件中:

1
2
3
4
5
6
7
8
[program:my_script]
command=python3 /home/user/scripts/my_script.py
directory=/home/user/scripts
autostart=true
autorestart=true
startsecs=5
stdout_logfile=/var/log/my_script.out.log
stderr_logfile=/var/log/my_script.err.log
参数 含义
command 要执行的命令
directory 工作目录
autostart 启动 supervisord 时自动启动
autorestart 异常退出后是否自动重启
startsecs 启动后运行多少秒才算成功
stdout_logfile 标准输出日志路径
stderr_logfile 错误日志路径
启动supervisord守护进程:
1
supervisord -c supervisord.conf

和systemd一样,supervisord也有一些管理任务的命令:

1
2
3
supervisorctl -c supervisord.conf status
supervisorctl -c supervisord.conf restart my_script
supervisorctl -c supervisord.conf stop my_script

也可以利用supervisord进行不同gpu任务分发,不同gpu上运行不同进程并守护的骚操作,首先,在你的模型任务代码中加上通过参数指定gpu的逻辑:

1
2
3
4
5
6
7
8
9
import torch
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--gpu', type=int, default=0)
args = parser.parse_args()

device = torch.device(f"cuda:{args.gpu}" if torch.cuda.is_available() else "cpu")
model.to(device)

然后,指定不同的gpu进行进程守护:

1
2
3
4
5
[program:worker1]
command=python3 /opt/scripts/train_model.py --gpu 0

[program:worker2]
command=python3 /opt/scripts/train_model.py --gpu 1

3. Docker + restart policy

Docker 提供了一种机制叫做 restart policy(重启策略),用来控制当容器退出或系统重启时,是否自动重启该容器。
对于一个Dockerfile,可以加上 --restart always运行。

1
2
docker build -t my-capture .
docker run -d --name my_capture_container --restart always my-capture

这个容器中的 Python 脚本崩溃时自动重启。

当然,在docker-compose.yml 中可以这样配置:

1
2
3
4
5
6
7
8
services:
camera_worker:
build: .
restart: always
volumes:
- ./logs:/app/logs
ports:
- "8000:8000"

当然,如果想要在linux中开机自启动容器,除了上面的,只要再使得docker自动启动即可:

1
sudo systemctl enable docker

这个命令会把 Docker 服务注册到 systemd 中,下次系统启动时会自动启动 Docker 服务, 也就自动拉起了 --restart always 的容器。

设置完之后,你可以检查一下重启策略是否配置好:

1
docker inspect your_container_name | grep -i restart