文章目录
- 一、概述
-
- [🚀 1. 启动 Supervisor 服务端](#🚀 1. 启动 Supervisor 服务端)
-
- [1.1 手动命令启动 (`supervisord`)](#1.1 手动命令启动 (
supervisord)) - [1.2 系统服务管理 (`systemctl`)](#1.2 系统服务管理 (
systemctl)) - [1.3 总结对比表](#1.3 总结对比表)
- [1.4 建议](#1.4 建议)
- [1.1 手动命令启动 (`supervisord`)](#1.1 手动命令启动 (
- [🛠️ 2. 管理子进程 (`supervisorctl`)](#🛠️ 2. 管理子进程 (
supervisorctl)) - [⚙️ 3. 如何配置你的项目](#⚙️ 3. 如何配置你的项目)
- [💡 4. 开启 Web 可视化界面](#💡 4. 开启 Web 可视化界面)
- [💡 5. 不同类型程序在command中的启动配置](#💡 5. 不同类型程序在command中的启动配置)
- [二、 安装](#二、 安装)
-
- [📦 方式一:系统包管理器安装(推荐新手或生产环境)](#📦 方式一:系统包管理器安装(推荐新手或生产环境))
- [💻 方式二:通过 pip 安装(跨平台通用方案)](#💻 方式二:通过 pip 安装(跨平台通用方案))
- [⚠️ 补充说明](#⚠️ 补充说明)
- 三、问题处理
-
- [🚀 1、Supervisor 启动后,会将conf.d中的服务启动吗](#🚀 1、Supervisor 启动后,会将conf.d中的服务启动吗)
-
- [⚙️ 1. 建立关联(主配置文件)](#⚙️ 1. 建立关联(主配置文件))
- [🚀 2. 触发启动(子进程配置)](#🚀 2. 触发启动(子进程配置))
- [💡 两种常见的"启动"场景](#💡 两种常见的“启动”场景)
- [⚙️ 2、核心操作:修改配置文件后如何生效](#⚙️ 2、核心操作:修改配置文件后如何生效)
-
- [📋 其他实用命令](#📋 其他实用命令)
- 💡3、如何判断服务是否已经起来了
-
- [📊 1. 查看子进程的运行状态(最核心)](#📊 1. 查看子进程的运行状态(最核心))
- [🔍 2. 进阶排查(如果状态不正常)](#🔍 2. 进阶排查(如果状态不正常))
- [💡 4、如果启动的子进程服务异常了,supervisor可以检测到吗](#💡 4、如果启动的子进程服务异常了,supervisor可以检测到吗)
-
- [1. 进程级别的异常(最基础的兜底)](#1. 进程级别的异常(最基础的兜底))
- [2. 启动阶段的异常(防止无限重启死循环)](#2. 启动阶段的异常(防止无限重启死循环))
- [3. 进阶场景:进程还在,但业务已经"假死"](#3. 进阶场景:进程还在,但业务已经“假死”)
- [💡 总结建议](#💡 总结建议)
一、概述
在服务器运维与后端开发中,Supervisor 是一个极其强大的进程管理工具。它可以将普通的 Python 脚本、Go 二进制文件、Java 应用或各类 Shell 脚本转化为稳定的后台服务(Daemon),并在程序发生异常崩溃时自动重启。
Supervisor 主要包含两个核心命令行工具:supervisord(服务端)和 supervisorctl(客户端)。以下是为你整理的常用命令速查与使用指南。
🚀 1. 启动 Supervisor 服务端
1.1 手动命令启动 (supervisord)
supervisord 是 Supervisor 的服务器端程序,负责读取配置文件并启动、管理子进程。
以下三个命令是直接调用 Supervisor 的主程序 supervisord。它们通常用于调试、临时测试,或者在没有配置系统服务(Systemd)的环境下使用。
-
指定配置文件启动(最常用) :
bashsupervisord -c /etc/supervisor/supervisord.conf- 作用: 告诉程序去哪里找配置文件。如果不加
-c,它会去默认路径找,但显式指定更稳妥。 - 特点: 默认会以守护进程(Daemon) 的方式在后台运行。终端关闭后它依然在跑。
- 作用: 告诉程序去哪里找配置文件。如果不加
-
前台运行(方便调试查看日志) :
bashsupervisord -n # 或者 supervisord --nodaemon- 作用: 强制 Supervisor 不进入后台,直接在当前终端窗口打印日志。
- 场景: 当你发现服务起不来,或者想看实时的报错信息时,用这个命令非常有效。注意: 如果你关掉这个终端窗口,Supervisor 就会停止运行。
-
以特定用户身份运行 :
bashsupervisord -u www-data- 作用: 指定 Supervisor 进程以哪个 Linux 用户的权限去运行。
- 场景: 出于安全考虑,有时候不希望用 root 权限运行,或者需要访问特定用户的文件权限时使用。
1.2 系统服务管理 (systemctl)
- 命令:
sudo systemctl start supervisor - 本质: 这是调用 Linux 的初始化系统(Systemd)来管理 Supervisor。Systemd 内部其实也是执行了类似
supervisord -c ...的命令,但它多了一层"包装"。 - 核心优势:
- 开机自启: 配合
systemctl enable supervisor,服务器重启后 Supervisor 会自动启动。手动敲命令做不到这一点。 - 统一管理: 你可以用统一的标准命令(
start,stop,restart,status)来管理它,不用去记复杂的参数。 - 环境隔离与日志: Systemd 会接管一部分环境变量和日志输出(虽然 Supervisor 自己也有日志,但 Systemd 也能记录它的启动状态)。
- 依赖管理: 可以配置让 Supervisor 在网络就绪或数据库启动后再启动。
- 开机自启: 配合
1.3 总结对比表
| 特性 | 图片中的命令 (手动) | systemctl start (系统服务) |
|---|---|---|
| 启动方式 | 直接运行二进制文件 | 通过 Systemd 守护进程管理 |
| 是否后台运行 | -c 默认后台;-n 前台 |
始终在后台运行 |
| 开机自启 | ❌ 不支持 (需额外配置 rc.local 等) | ✅ 支持 (systemctl enable) |
| 崩溃重启 | ❌ 仅靠 Supervisor 自身机制 | ✅ Systemd + Supervisor 双重保障 |
| 适用场景 | 调试报错、临时测试、Docker容器内 | 生产环境标准用法 |
1.4 建议
- 在生产环境中: 请务必使用
systemctl start supervisor。这样即使服务器意外重启,你的服务也能自动恢复。 - 在排查问题时: 如果
systemctl start失败了,或者你不知道为什么起不来,可以尝试用supervisord -n在前台运行,这样能直接在屏幕上看到具体的 Python 报错堆栈信息。
通过上述对比可以看出,根据实际场景选择合适的启动方式能显著提高运维效率。
🛠️ 2. 管理子进程 (supervisorctl)
supervisorctl 是客户端命令行工具,用于向服务端发送指令,管理你配置好的 Python 项目或其他程序。
基础进程控制:
- 查看所有进程状态 :
supervisorctl status - 启动某个进程 :
supervisorctl start <项目名>(例如:supervisorctl start my_python_app) - 停止某个进程 :
supervisorctl stop <项目名> - 重启某个进程 :
supervisorctl restart <项目名> - 实时查看进程日志 :
supervisorctl tail -f <项目名>
批量操作:
- 启动/停止/重启所有进程 :
supervisorctl start all/stop all/restart all
配置更新(非常重要):
当你修改了 .conf 或 .ini 配置文件后,需要执行以下命令让新配置生效:
- 重新读取配置 :
supervisorctl reread - 应用配置更新 :
supervisorctl update(会根据最新配置启动新程序或重启有改动的程序) - 完全重载并重启所有进程 :
supervisorctl reload
其他高级命令:
- 关闭 Supervisor 服务端 :
supervisorctl shutdown - 进入交互式 Shell 模式 :直接输入
supervisorctl,之后可以直接输入status,start xxx等命令,退出请输入quit。
⚙️ 3. 如何配置你的项目
在使用上述命令前,你需要先在配置文件中定义你的项目。通常建议在 /etc/supervisor/conf.d/ 目录下为每个项目创建一个独立的 .conf 或 .ini 文件。
一个标准的 Python 项目配置模板如下:
ini
[program:my_python_app]
; 你的Python项目启动命令(建议使用虚拟环境的绝对路径)
command=/usr/bin/python3 /path/to/your/main.py
; 项目所在的目录
directory=/path/to/your/project
; 以哪个用户身份运行
user=root
; 是否随supervisord启动而自动启动
autostart=true
; 程序意外退出时是否自动重启 (unexpected表示仅在非预期退出码时重启)
autorestart=true
; 启动几秒后没有异常退出,就认为启动成功
startsecs=5
; 标准输出日志路径
stdout_logfile=/var/log/my_python_app.log
; 将错误日志重定向到标准输出日志
redirect_stderr=true
; 设置环境变量(如果需要)
environment=PYTHONPATH="/path/to/your/project",DEBUG="false"
💡 4. 开启 Web 可视化界面
如果你不想每次都敲命令,可以开启 Supervisor 自带的 Web 管理界面。在主配置文件(supervisord.conf)中找到并取消 [inet_http_server] 部分的注释:
ini
[inet_http_server]
port=127.0.0.1:9001 ; 访问地址和端口
username=admin ; 登录用户名(可选)
password=123456 ; 登录密码(可选)
配置好后,通过浏览器访问 http://127.0.0.1:9001 即可直观地看到所有进程的状态并进行启停操作。
💡 5. 不同类型程序在command中的启动配置
虽然 Supervisor 本身是用 Python 编写的,但它管理的对象与编程语言毫无关系。它通过底层的 fork/exec 机制来启动程序,因此任何能在 Linux/Unix 终端里通过命令行启动的程序,都可以交给 Supervisor 来管理。
无论是哪种语言写的项目,只要你能写出它的启动命令,Supervisor 就能把它当成一个子进程进行监控、自动重启和日志收集。以下是一些常见的跨语言管理示例:
- Java 项目 (如 Spring Boot):
- 配置核心:
command=java -jar /你的路径/app.jar
- 配置核心:
- Go 或 C/C++ 项目 (编译后的二进制文件):
- 配置核心:
command=/你的路径/编译好的可执行程序
- 配置核心:
- Node.js 项目 :
- 配置核心:
command=node /你的路径/server.js
- 配置核心:
- 各类脚本 (Shell、PHP、Ruby 等):
- 配置核心:
command=/bin/bash /你的路径/script.sh
- 配置核心:
在 Supervisor 的配置文件(.conf)中,你只需要在 [program:xxx] 模块下指定好对应的 command(启动命令)、directory(工作目录)以及日志输出路径即可。
所以,你可以放心地用 Supervisor 统一管理服务器上各种技术栈的后端服务、定时任务或消息队列消费者,它能提供一套非常统一且高效的运维标准。
二、 安装
Supervisor 主要有两种常见的安装方式:使用系统的包管理器(如 apt、yum)或者使用 Python 的包管理器 pip。你可以根据你的实际环境和需求来选择:
📦 方式一:系统包管理器安装(推荐新手或生产环境)
如果你使用的是主流的 Linux 发行版,强烈建议直接使用系统自带的包管理器来安装。这种方式会自动处理好各种依赖关系,并且会自动配置好默认的文件路径和开机自启服务,非常省心。
-
Ubuntu / Debian 系统:
bashsudo apt update && sudo apt install supervisor -y -
CentOS 7 / RHEL 7 系统:
bashsudo yum install epel-release -y && sudo yum install supervisor -y -
CentOS 8+ / Fedora 系统:
bashsudo dnf install epel-release -y && sudo dnf install supervisor -y
💻 方式二:通过 pip 安装(跨平台通用方案)
如果你的系统仓库里没有 Supervisor(比如某些精简版的 Linux 镜像),或者你需要指定特定的版本、在 Python 虚拟环境中隔离使用,那么 pip 就是最佳选择。
-
安装命令:
bashsudo pip3 install supervisor -
注意事项: 使用
pip安装后,通常需要手动生成初始配置文件 ,并自行配置为系统服务(systemd)来实现开机自启。- 生成默认配置文件:
echo_supervisord_conf | sudo tee /etc/supervisord.conf
- 生成默认配置文件:
⚠️ 补充说明
- Windows 用户注意: Supervisor 是基于 Python 开发的,仅支持类 Unix 系统(如 Linux、macOS),不支持在 Windows 环境下运行。
- 总结建议: 如果是为了在生产服务器上快速部署且追求稳定,优先选系统包管理器 ;如果是在开发环境、特定版本的 Python 环境中,或者系统源里没有这个包,再考虑用
pip安装。
三、问题处理
🚀 1、Supervisor 启动后,会将conf.d中的服务启动吗
是的,Supervisor 启动后会自动将 conf.d 目录中的服务启动起来。
但这背后有一个关键的前提条件:你的主配置文件(通常是 /etc/supervisor/supervisord.conf)中必须配置了 [include] 模块,告诉 Supervisor 去读取 conf.d 里的文件。
以下是它自动启动服务的完整工作逻辑:
⚙️ 1. 建立关联(主配置文件)
Supervisor 的主配置文件里通常会有这样一段配置:
ini
[include]
files = /etc/supervisor/conf.d/*.conf
这行配置的作用就是告诉 Supervisor:"启动的时候,记得把 /etc/supervisor/conf.d/ 目录下所有以 .conf 结尾的文件都加载进来"。
🚀 2. 触发启动(子进程配置)
当你在 conf.d 下为某个服务(比如 satellite_server)写好配置文件时,里面通常会包含一个核心参数:
ini
[program:satellite_server]
command=python /path/to/your/server.py
autostart=true
只要设置了 autostart=true(这也是默认值),当 Supervisor 主进程启动并读取到这个配置后,就会立刻把这个服务拉起来。
💡 两种常见的"启动"场景
- 首次启动或服务器重启: 当你执行
systemctl start supervisord或者服务器开机自启时,Supervisor 会先自己跑起来,然后按照[include]的路径扫描所有子配置文件,并把标记了autostart=true的服务全部批量启动。 - 运行中新增服务: 如果 Supervisor 已经在运行了,你新加了一个配置文件到
conf.d里,它不会自动感知。这时你需要手动执行sudo supervisorctl reread和sudo supervisorctl update,它才会读取新配置并启动这个新服务。
所以,只要你确保主配置文件的 [include] 路径正确,且子配置文件里写了 autostart=true,Supervisor 就能完美地帮你托管并自动拉起这些服务。
⚙️ 2、核心操作:修改配置文件后如何生效
当你修改或新增了 /etc/supervisor/conf.d/ 目录下的 .conf 文件后,千万不要直接去重启整个服务。标准的生效流程是:
-
重新读取配置 (让 Supervisor 发现新的改动):
bashsudo supervisorctl reread -
更新并应用变更 (自动重启有改动的进程,启动新加的进程):
bashsudo supervisorctl update
📋 其他实用命令
-
实时查看某个服务的日志输出 (类似
tail -f,按 Ctrl+C 退出):bashsudo supervisorctl tail -f your_server -
查看某个服务的错误日志 :
bashsudo supervisorctl tail your_server stderr -
关闭整个 Supervisor 服务端 (一般不需要用,除非你要彻底关停它):
bashsudo supervisorctl shutdown
💡3、如何判断服务是否已经起来了
可以通过以下几个步骤来快速确认:
📊 1. 查看子进程的运行状态(最核心)
这是最直接的方法。在终端输入以下命令:
bash
sudo supervisorctl status
- 成功的标志 :如果看到你的服务名后面显示
RUNNING,并且有具体的pid(进程号)和uptime(已运行时长),就说明服务已经完全起来了。- 示例输出:
your_server RUNNING pid 12345, uptime 0:15:30
- 示例输出:
- 失败的标志 :如果显示
STOPPED(已停止)、FATAL(启动失败)或BACKOFF(反复重启失败),则说明服务没有正常跑起来。
🔍 2. 进阶排查(如果状态不正常)
如果在第 1 步中发现服务不是 RUNNING 状态,可以用以下两招快速定位问题:
-
实时查看日志 :看看服务启动时到底报了什么错。
bashsudo supervisorctl tail -f <你的服务名> -
尝试手动启动 :有时候只是意外停止了,手动拉一下试试。
bashsudo supervisorctl start <你的服务名>
💡 4、如果启动的子进程服务异常了,supervisor可以检测到吗
可以,Supervisor 能够非常精准地检测到 your_server 及其启动的子服务的异常。
它通过一套"被动监听 + 主动探测"的双重机制来保障服务状态。具体是如何检测的,可以分为以下几个层面:
1. 进程级别的异常(最基础的兜底)
只要你的 your_server 进程因为代码报错、内存溢出等原因直接崩溃退出了,Supervisor 就能立刻感知到。
- 原理: Supervisor 作为父进程,操作系统会在子进程(即
your_server)退出时向它发送一个SIGCHLD信号。Supervisor 捕获到这个信号后,就会知道子进程挂了,并根据你配置的autorestart=true自动把它拉起来。 - 效果: 即使程序发生未捕获的异常导致闪退,也能实现"无缝续命"。
2. 启动阶段的异常(防止无限重启死循环)
如果 your_server 在刚启动时就报错退出,Supervisor 也有很好的保护机制。
- 原理: 配置中的
startsecs参数规定了进程必须稳定运行多少秒才算"启动成功"。如果进程在startsecs时间内就退出了,Supervisor 会认为启动失败。为了避免陷入"启动-崩溃-再启动"的死循环,它会结合startretries(默认重试3次)参数进行限制。 - 效果: 如果连续几次都启动失败,Supervisor 会将该服务的状态标记为
FATAL(致命错误),并停止无意义的自动重启,方便你及时去排查日志。
3. 进阶场景:进程还在,但业务已经"假死"
这是很多开发者容易忽略的一点。Supervisor 默认监控的是操作系统的进程状态 。如果你的 your_server 进程虽然没有退出,但因为死锁、卡死或者内部逻辑错误导致无法提供正常服务(比如端口不通了、接口一直转圈),Supervisor 默认是检测不到这种"假死"状态的。
针对这种情况,通常有以下两种解决方案:
- 方案 A:应用层自我终结(推荐)
在你的 Python 代码中加入健康检查逻辑。比如定时去检查一下数据库或 Redis 连接是否正常,如果发现核心依赖断了,就让程序主动执行sys.exit(1)退出。一旦进程退出,Supervisor 就会立刻接管并帮你重启。 - 方案 B:外部脚本辅助监控
写一个简单的 Shell 脚本或使用第三方工具,每隔几分钟用curl请求一下your_server的健康检查接口(例如http://127.0.0.1:端口/health)。如果接口返回异常或超时,就在脚本里执行supervisorctl restart your_server命令强制重启它。
💡 总结建议
对于 your_server 来说,只要配置好了 autorestart=true,绝大多数崩溃和异常退出的情况,Supervisor 都能完美兜底并自动恢复。如果想防范"进程假死",建议在代码中增加主动退出的逻辑,这样能最大程度保证服务的稳定性。