Supervisor (Linux)

supervisor 是一个 Linux 进程控制系统,允许您在类 UNIX 操作系统上监视和控制多个进程。它特别适用于管理需要连续运行的进程,以及监视和控制在后台运行的进程。

何时使用

supervisor 非常适合管理需要持续正常运行和强大进程控制的 Python Web 应用程序。当您需要广泛的进程管理、监视、日志管理以及对应用程序进程的启动、停止和重启进行自定义控制时,它特别有用。

有关详细理解和更多信息,请参阅官方 Supervisor 文档

替代方案

对于不同的部署场景,请考虑以下替代方案:

  • Docker

    适用于容器化环境,提供隔离和可扩展性。

  • systemd

    一个系统和服务管理器,集成到许多 Linux 发行版中以管理系统进程。

    备注

    官方文档即将推出

  • 手动使用 ASGI 服务器

    通过使用 ASGI 服务器(如 Uvicorn、Hypercorn、Daphne 等)运行应用程序来直接控制。

此资源提供了有关安装、配置和使用 supervisor 进行服务管理的全面指导。

设置

supervisor 使用配置文件来定义服务。您可以在 Supervisor 配置文档 中了解有关配置文件的更多信息。

示例 supervisor 配置文件
[program:exampleapp]  # 定义服务名称。
directory=/opt/exampleapp/src  # 指定服务应运行的目录。
command=/opt/exampleapp/venv/bin/litestar app.py  # 指定运行服务的命令。
redirect_stderr=true  # 将 stderr 重定向到 stdout。
stdout_logfile=/var/log/exampleapp.log  # 指定要写入的日志文件。
stdout_logfile_backups=10  # 指定要保留的备份数量。
autostart=true  # 指定服务应在 ``supervisor`` 启动时自动启动。
autorestart=true  # 指定服务如果意外退出应自动重启。

您可以将上述配置文件放在 /etc/supervisor/conf.d/exampleapp.conf 中。 创建配置文件后,您需要重新加载 supervisor 配置以加载新的服务文件。

有用的命令
重新加载 supervisor 配置
sudo supervisorctl reread
sudo supervisorctl update
启动/停止/重启/状态
sudo supervisorctl start exampleapp
sudo supervisorctl stop exampleapp
sudo supervisorctl restart exampleapp
sudo supervisorctl status exampleapp
查看日志
sudo supervisorctl tail -f exampleapp

现在您可以启动应用程序了。

  1. 如果服务尚未运行,则启动服务:sudo supervisorctl start exampleapp

  2. 通过检查输出是否有错误来确保其正常运行:sudo supervisorctl status exampleapp

  3. 确认后,您的 Litestar 应用程序应该可以访问(默认在 http://0.0.0.0:8000)。

之后,您就完成了!现在可以使用 supervisor 来管理您的应用程序。 以下部分旨在提供一些建议以使事情更易于管理,它们不是必需的。

建议

小技巧

这延续了上面的设置,但提供了一些使事情更易于管理的建议。

别名

创建一个别名文件:/etc/profile.d/exampleapp.sh

这就是让我们可以简单地使用 exampleapp start 而不是 sudo supervisorctl start exampleapp 的魔法所在。

别名示例
别名文件提供的示例命令
exampleapp start
exampleapp stop
exampleapp restart
exampleapp status
exampleapp watch
示例别名文件
 1exampleapp() {
 2  case $1 in
 3    start)
 4      echo "Starting exampleapp..."
 5      sudo supervisorctl start exampleapp
 6      ;;
 7
 8    stop)
 9      echo "Stopping exampleapp..."
10      sudo supervisorctl stop exampleapp
11      ;;
12
13    restart)
14      echo "Restarting exampleapp..."
15      sudo supervisorctl restart exampleapp
16      ;;
17
18    status)
19      echo "Checking status of exampleapp..."
20      sudo supervisorctl status exampleapp
21      ;;
22
23    watch)
24      echo "Tailing logs for exampleapp..."
25      sudo supervisorctl tail -f exampleapp
26      ;;
27
28    help)
29      cat << EOF
30      Available options:
31        exampleapp start    - Start the exampleapp service
32        exampleapp stop     - Stop the exampleapp service
33        exampleapp restart  - Restart the exampleapp service
34        exampleapp status   - Check the status of the exampleapp service
35        exampleapp watch    - Tail the logs for the exampleapp service
36      EOF
37      ;;
38
39    *)
40      echo "Unknown command: $1"
41      echo "Use 'exampleapp help' for a list of available commands."
42      ;;
43  esac
44}

要在不重启会话的情况下激活别名,请使用 source /etc/profile.d/exampleapp.sh。 使用 watch 命令可以让您监视应用程序的实时输出。

更新脚本

exampleapp 函数可以扩展以包含 update 命令,方便应用程序的完整更新过程:

更新脚本示例
示例更新命令
 1exampleapp() {
 2  case $1 in
 3    # ... 其他情况 ... #
 4
 5    update)
 6      echo "Updating exampleapp..."
 7
 8      # 停止服务
 9      echo " > Stopping service..."
10      sudo supervisorctl stop exampleapp
11
12      # 更新应用程序文件
13      echo " > Pulling latest changes from repository..."
14      cd /opt/exampleapp
15      git fetch --all
16      git reset --hard origin/master
17
18      # 更新 Supervisor 配置和别名
19      echo " > Updating Supervisor and shell configurations..."
20      sudo ln -sf /opt/exampleapp/server/service.conf /etc/supervisor/conf.d/exampleapp.conf
21      sudo ln -sf /opt/exampleapp/server/alias.sh /etc/profile.d/exampleapp.sh
22      source /etc/profile.d/exampleapp.sh
23
24      # 更新 Supervisor 以应用新配置
25      echo " > Reloading Supervisor configuration..."
26      sudo supervisorctl reread
27      sudo supervisorctl update
28
29      # 使用 requirements.txt 更新 Python 依赖项
30      # 这里您可以替换为 poetry、pdm 等,减轻对
31      # requirements.txt 文件和虚拟环境激活的需求。
32      source venv/bin/activate
33      echo " > Installing updated dependencies..."
34      python3 -m pip install -r requirements.txt
35      deactivate
36
37      # ... 其他更新过程,如文档构建、清理等 ... #
38
39      echo "Update process complete."
40
41      # 提示启动服务
42      read -p "Start the service? (y/n) " -n 1 -r
43      echo
44      if [[ $REPLY =~ ^[Yy]$ ]]
45      then
46          echo " > Starting service..."
47          sudo supervisorctl start exampleapp
48      fi
49      ;;
50
51    # ... #
52  esac
53}

此更新过程包括以下步骤:

  1. 停止服务: 在进行更改之前安全地停止应用程序。

  2. Git 操作: 确保从存储库中拉取最新代码。

  3. 配置符号链接: 更新 supervisor 配置和 shell 别名以反映任何更改。

  4. Supervisor 重新加载: 将新的配置设置应用于 supervisor 服务。

  5. 依赖项更新: 根据锁定文件或 requirements.txt 中的定义安装或更新 Python 依赖项。

  6. 用户提示: 提供在更新后立即启动服务的选择。

执行

运行 exampleapp update 命令来执行此更新过程。 它简化了新代码和配置更改的部署,确保流畅且一致的应用程序更新周期。