Supervisor 实战指南:从安装到进程管理
1. 初识Supervisor你的进程“贴身管家”如果你在Linux服务器上跑过一些自己写的脚本、Web服务或者定时任务肯定遇到过这样的烦恼程序在终端前台跑得好好的一关掉SSH窗口或者终端不小心断开进程就跟着挂了。或者程序运行久了不知道什么原因突然崩溃还得手动登录服务器去重启。这种时候你就需要一个“贴身管家”7x24小时帮你盯着这些进程一旦它们“偷懒”或者“罢工”就立刻把它们拉回来继续干活。这个管家就是Supervisor。它是一个用Python写的进程管理工具专门用来把普通的命令行程序变成可靠的后台守护进程daemon。我最早接触它是在管理一个Python写的爬虫项目当时脚本经常因为网络波动异常退出每次都得半夜爬起来手动重启苦不堪言。自从用上Supervisor设置好自动重启终于能睡个安稳觉了。简单来说Supervisor的核心能力就三点进程守护把你指定的程序变成后台服务不随终端退出而终止。自动重启当管理的进程意外退出时比如代码报错、被误杀它能自动重新启动保障服务持续可用。集中管理提供了一个统一的命令行工具supervisorctl和可选的Web界面来查看所有进程状态、启停、重启再也不用记一堆复杂的ps、kill、nohup命令了。它特别适合管理那些没有自带守护进程功能的脚本、单文件应用或者像Gunicorn、uWSGI这类应用服务器。对于运维和开发者来说Supervisor极大地简化了服务部署和日常维护的复杂度。2. 两种安装方式选对方法事半功倍安装Supervisor本身不复杂但根据你的系统环境和网络情况选择合适的方法能避免不少坑。主要有两种主流方式通过系统包管理器安装和通过Python的pip安装。2.1 使用系统包管理器安装推荐新手这是最省心、最快捷的方式适合绝大多数常见的Linux发行版。系统包管理器会自动处理好依赖关系和初始化配置。在Ubuntu或Debian上sudo apt update sudo apt install supervisor -y安装完成后Supervisor服务会自动启动并且配置好了开机自启。主配置文件通常在/etc/supervisor/supervisord.conf进程的独立配置文件可以放在/etc/supervisor/conf.d/目录下。在CentOS、RHEL或Fedora上 对于CentOS 7/RHEL 7需要先启用EPELExtra Packages for Enterprise Linux仓库因为Supervisor在默认仓库里可能没有。# CentOS 7/RHEL 7 sudo yum install epel-release -y sudo yum install supervisor -y # CentOS 8/RHEL 8或Fedora sudo dnf install supervisor -y同样安装后服务会自动配置。在CentOS系列中主配置文件路径通常是/etc/supervisord.conf而/etc/supervisord.d/是存放子配置的目录。优点安装简单与系统集成好有标准的服务管理命令如systemctl start supervisor。缺点版本可能不是最新的。比如在一些老系统上通过yum安装的可能是Python 2版本的Supervisor。2.2 使用Python pip安装追求新版本或定制如果你的系统包管理器里的版本太旧或者你希望使用Python 3环境下的最新版Supervisorpip安装是更好的选择。这要求你的系统已经安装了pip。# 确保已安装pipPython 3 sudo apt install python3-pip -y # Ubuntu/Debian # 或 sudo yum install python3-pip -y # CentOS # 使用pip安装 sudo pip3 install supervisor通过pip安装后不会自动生成系统服务文件。你需要手动创建配置文件并设置开机启动。生成默认配置文件的方法是echo_supervisord_conf /etc/supervisord.conf然后你需要自己创建一个Systemd服务单元文件比如/etc/systemd/system/supervisord.service来管理它这样才能用systemctl控制。对于新手我强烈建议先用包管理器安装等熟悉了再考虑pip安装的方式。踩坑提醒网上有些老教程会教你用Python 2的easy_install或者python setup.py install来安装这很容易遇到Python版本兼容问题。我当年就踩过这个坑在Ubuntu 22.04上默认只有Python 3按照老教程装Python 2版本的Supervisor各种依赖报错折腾了半天。所以请直接使用上述两种现代方法。3. 核心概念与首次启动理解它在做什么安装好后别急着配置你的应用。先花两分钟理解两个核心命令和它们的角色这对后续排错至关重要。supervisord这是Supervisor的服务端/守护进程。它才是真正干活的那个“管家”。你通过配置文件告诉它要管理哪些程序然后启动supervisord它就会常驻内存负责启动、监控和管理你定义的所有子进程。我们修改配置后最终都是要通知supervisord重新加载。supervisorctl这是Supervisor的客户端/管理工具。它是你和“管家”supervisord沟通的桥梁。通过它你可以查看所有进程的状态、启动、停止、重启某个或全部进程而无需直接去操作进程ID。首次启动与验证 假设你是通过包管理器安装的Supervisor服务很可能已经运行了。你可以用以下命令检查# 查看服务状态 sudo systemctl status supervisor # 如果没运行启动它 sudo systemctl start supervisor # 设置开机自启 sudo systemctl enable supervisor服务启动后就可以使用supervisorctl来检查了sudo supervisorctl status如果一切正常你会看到类似这样的输出目前应该是空的因为你还没添加任何要管理的程序这表示Supervisor本身已经就绪正在等待你的指令。4. 配置文件深度解析从入门到精通Supervisor的强大和灵活几乎全部体现在它的配置文件里。主配置文件定义了Supervisor自身的行为而每个被管理的程序又有自己独立的配置段。我们来把关键配置项掰开揉碎了讲。4.1 主配置文件 (supervisord.conf) 核心部分用包管理器安装后主配置文件通常已经存在。我们可以用cat或vim查看/etc/supervisor/supervisord.conf或/etc/supervisord.conf。文件里有很多以分号;开头的注释行它们说明了每个选项的作用。我们关注几个核心区块[unix_http_server]这是Supervisor内部通信的Unix Socket配置。supervisorctl默认通过这个socket与supervisord对话。[unix_http_server] file/var/run/supervisor.sock ; socket文件路径 ; chmod0700 ; socket文件权限默认0700 ; chownnobody:nogroup ; socket文件属主 ; usernameuser ; 连接用户名如果启用认证 ; password123 ; 连接密码通常保持默认即可。如果遇到supervisorctl连接不上的错误可以检查这个socket文件是否存在以及权限是否正确。[inet_http_server]启用Web管理界面。如果你想通过浏览器比如http://服务器IP:9001来管理进程就需要取消注释并配置这部分。[inet_http_server] port127.0.0.1:9001 ; 监听IP和端口。如果只允许本机访问就用127.0.0.1。想外网访问改成0.0.0.0但务必设置用户名密码 usernameadmin ; 登录用户名 passwordyour_strong_password ; 登录密码安全警告如果端口对外开放username和password必须设置且密码不要用简单的。[supervisord]定义Supervisor守护进程自身的日志、PID文件等。[supervisord] logfile/var/log/supervisor/supervisord.log ; 主日志路径 logfile_maxbytes50MB ; 单个日志文件最大大小 logfile_backups10 ; 保留的旧日志文件数量 loglevelinfo ; 日志级别 (debug, info, warn, error) pidfile/var/run/supervisord.pid ; PID文件路径 nodaemonfalse ; 是否在前台运行false表示以守护进程运行日志文件的位置很重要出问题时首先要来这里查。[include]这是最实用的配置之一它允许你将不同程序的配置分散到多个文件中便于管理。[include] files /etc/supervisor/conf.d/*.conf /etc/supervisor/conf.d/*.ini这意味着supervisord会自动加载/etc/supervisor/conf.d/目录下所有以.conf或.ini结尾的文件。我们之后为每个应用创建的配置文件就放在这里。4.2 程序配置 ([program:xxx]) 详解这才是重头戏。假设我们要管理一个名为my_web_app的Gunicorn应用我们可以在/etc/supervisor/conf.d/my_web_app.conf里这样写[program:my_web_app] ; 基本命令与目录 command/usr/local/bin/gunicorn myapp.wsgi:application -w 4 -b 0.0.0.0:8000 ; 启动命令 directory/opt/myapp ; 执行命令前先切换到此目录 userwww-data ; 以哪个用户身份运行进程重要不要用root跑应用 autostarttrue ; 当supervisord启动时自动启动该程序 autorestarttrue ; 程序退出后自动重启。可选值false, true, unexpected仅在意外退出时重启 ; 启动控制 startsecs5 ; 程序启动后持续运行5秒无异常才认为是启动成功 startretries3 ; 启动失败后的重试次数 exitcodes0,2 ; 哪些退出码被认为是“预期内的成功退出”不触发重启。默认0,2。 ; 停止信号 stopsignalTERM ; 停止进程时发送的信号默认是TERM。也可以是INT, QUIT, KILL, USR1等。 stopwaitsecs10 ; 发送SIGKILL强制终止前等待进程自己退出的时间秒 ; 日志管理极其重要 stdout_logfile/var/log/supervisor/my_web_app_stdout.log ; 标准输出日志 stdout_logfile_maxbytes50MB ; 标准输出日志文件最大大小 stdout_logfile_backups10 ; 保留多少个标准输出日志备份 stderr_logfile/var/log/supervisor/my_web_app_stderr.log ; 标准错误日志 stderr_logfile_maxbytes50MB stderr_logfile_backups10 redirect_stderrtrue ; 是否将标准错误重定向到标准输出。通常设为true方便在一个日志文件里查看所有输出。 ; 环境变量 environmentPYTHONPATH/opt/myapp,DJANGO_SETTINGS_MODULEmyapp.settings.production ; 设置环境变量多个用逗号分隔 ; 进程数量与命名 numprocs1 ; 启动的进程实例数量默认为1。如果大于1process_name必须包含%(process_num)s process_name%(program_name)s_%(process_num)02d ; 当numprocs1时进程名格式关键参数解读与实战经验command这是最重要的参数。必须确保命令能在指定的directory和user环境下正确执行。建议使用绝对路径。user强烈建议不要使用root。为你的应用创建一个专用系统用户如www-data,appuser用这个用户来运行更安全。autorestart我一般设为true确保服务异常退出后能自动恢复。如果你希望手动控制重启可以设为false。stdout_logfile和stderr_logfile务必设置这是你排查程序问题的第一现场。Supervisor会自动创建这些日志文件但目录需要存在且有写入权限。将标准错误重定向到标准输出redirect_stderrtrue可以让日志查看更集中。environment这是为进程注入环境变量的地方。比如设置Python路径、数据库连接变量、配置文件路径等非常有用。4.3 进程组配置 ([group:xxx])如果你有一组相关的进程需要统一管理比如一个微服务架构下的多个组件可以使用组。[group:my_microservices] programsservice_a, service_b, service_gateway ; 程序名用逗号分隔 priority999 ; 组启动优先级然后你可以用supervisorctl命令一次性操作整个组sudo supervisorctl start my_microservices:* # 启动组内所有进程 sudo supervisorctl stop my_microservices:* # 停止组内所有进程 sudo supervisorctl restart my_microservices:* # 重启组内所有进程5. 实战案例部署一个Python Web应用光说不练假把式。我们以一个典型的Python Django应用为例使用Gunicorn作为应用服务器用Supervisor来管理它。步骤1创建应用专属配置文件在/etc/supervisor/conf.d/目录下创建一个新文件例如django_myblog.confsudo vim /etc/supervisor/conf.d/django_myblog.conf步骤2写入配置内容假设你的Django项目路径是/home/appuser/myblog使用虚拟环境Gunicorn安装在虚拟环境中。[program:django_myblog] ; 使用虚拟环境中的Python和Gunicorn command/home/appuser/venv/bin/gunicorn myblog.wsgi:application --bind 0.0.0.0:8000 --workers 3 --threads 2 directory/home/appuser/myblog ; 项目根目录 userappuser ; 用专门的appuser运行 autostarttrue autorestarttrue startsecs10 startretries3 stopwaitsecs60 ; 给Gunicorn足够的时间处理完现有请求 stdout_logfile/var/log/supervisor/django_myblog_stdout.log stdout_logfile_maxbytes100MB stdout_logfile_backups5 stderr_logfile/var/log/supervisor/django_myblog_stderr.log stderr_logfile_maxbytes100MB stderr_logfile_backups5 redirect_stderrtrue ; 设置关键环境变量 environmentDJANGO_SETTINGS_MODULEmyblog.settings.production,PYTHONPATH/home/appuser/myblog,PATH/home/appuser/venv/bin:%(ENV_PATH)s步骤3让Supervisor加载新配置创建或修改配置文件后Supervisor不会自动读取。需要执行# 重新读取配置检查是否有新配置或配置有变动 sudo supervisorctl reread如果输出显示你的程序名例如django_myblog: available说明配置被识别。步骤4更新并启动新程序# 更新配置并启动新增的或有改动的程序不会重启未改动的程序 sudo supervisorctl update或者你也可以分两步走# 仅添加新程序到进程组如果之前没运行过 # sudo supervisorctl add django_myblog # 然后启动它 sudo supervisorctl start django_myblog步骤5检查状态sudo supervisorctl status django_myblog如果看到RUNNING状态并且pid后面有数字恭喜你部署成功了django_myblog RUNNING pid 12345, uptime 0:00:306. 日常管理与故障排查玩转supervisorctl配置好之后日常运维就靠supervisorctl了。它有一系列直观的命令。6.1 常用管理命令# 查看所有进程状态这是最常用的命令 sudo supervisorctl status # 查看单个进程状态 sudo supervisorctl status django_myblog # 启动、停止、重启单个进程 sudo supervisorctl start django_myblog sudo supervisorctl stop django_myblog sudo supervisorctl restart django_myblog # 启动、停止、重启所有进程 sudo supervisorctl start all sudo supervisorctl stop all sudo supervisorctl restart all # 重新加载配置文件注意这会重启所有程序 sudo supervisorctl reload # 仅更新配置新增的会启动修改的会重启移除的会停止 sudo supervisorctl update # 重新读取配置文件不重启任何程序 sudo supervisorctl reread # 进入交互式控制台可以连续执行多个命令 sudo supervisorctl # 进入后提示符会变成 supervisor然后可以直接输入命令如 status, stop all 等 # 输入 quit 或 CtrlD 退出6.2 日志查看与故障排查当进程状态显示FATAL,BACKOFF,EXITED等异常状态时就需要查日志了。首先查看Supervisor的主日志看有没有全局性错误sudo tail -f /var/log/supervisor/supervisord.log然后查看具体程序的输出日志就是我们配置里指定的stdout_logfile和stderr_logfile# 查看标准输出日志 sudo tail -f /var/log/supervisor/django_myblog_stdout.log # 查看标准错误日志如果redirect_stderrfalse sudo tail -f /var/log/supervisor/django_myblog_stderr.log程序启动失败的原因比如Python模块导入错误、端口被占用、权限问题等都会在这里打印出来。常见问题与解决状态为STARTING或BACKOFF通常是启动命令本身有错误或者启动后很快又退出了。仔细检查command命令的路径、参数以及startsecs是否设置得太短。状态为FATAL通常是根本启动不起来比如命令不存在、配置文件语法错误。检查supervisorctl reread时的输出。权限问题如果日志显示Permission denied检查user指定的用户是否有权执行command以及是否有权在directory下读写是否有权写入日志文件目录。我遇到过好几次因为日志目录权限不对导致进程启动失败的情况。端口冲突如果应用绑定端口失败检查端口是否已被其他程序占用。6.3 进程的“一生”与信号处理理解Supervisor如何控制进程的启动和停止有助于更精细地管理。在[program]配置中stopsignal和stopwaitsecs是关键。stopsignal默认是TERM即SIGTERM15号信号这是一个“礼貌”的终止信号程序收到后可以做一些清理工作再退出。如果你的程序对TERM信号没反应可以尝试INTSIGINT, 2号信号相当于CtrlC或QUITSIGQUIT, 3号信号。万不得已再用KILLSIGKILL, 9号信号这个信号无法被程序捕获会强制立即终止可能导致数据丢失。stopwaitsecs发送了stopsignal后Supervisor会等待这么多秒如果进程还没退出就会发送SIGKILL强制杀掉。对于像数据库、Web服务器这类需要时间处理完现有连接再退出的程序这个值应该设得大一些比如30或60秒。7. 进阶技巧与最佳实践掌握了基础再来点提升效率的技巧。1. 使用环境变量文件如果配置里有很多环境变量或者敏感信息如数据库密码可以单独写在一个文件里然后在配置中引用。[program:my_app] ... environmentHOME/home/appuser,PATH/usr/bin:%(ENV_PATH)s envfile/etc/supervisor/conf.d/my_app_env.conf ; 从文件加载环境变量在/etc/supervisor/conf.d/my_app_env.conf中SECRET_KEYyour_secret_key_here DB_PASSWORDyour_db_password_here注意envfile中的变量会覆盖environment中同名的变量。2. 进程依赖管理Supervisor本身不直接处理进程间的启动顺序依赖。但你可以通过priority参数和脚本技巧来模拟。priority值越小启动越早停止越晚。你可以让数据库的priority设为1Web服务器的priority设为999这样数据库会先启动后关闭。更复杂的依赖可以在command里写一个启动脚本在脚本中检查依赖服务是否就绪。3. 与Docker容器集成在Docker容器内使用Supervisor是一种常见模式用于管理容器内的多个进程比如Nginx Gunicorn。关键点在于必须让Supervisor在前台运行否则Docker容器会立刻退出。在Dockerfile的CMD或ENTRYPOINT中CMD [supervisord, -n, -c, /etc/supervisord.conf]-n参数就是让supervisord在前台运行。4. 配置文件版本管理将你的应用Supervisor配置文件/etc/supervisor/conf.d/下的文件纳入Git等版本控制系统。这样在部署新版本时可以方便地同步和回滚配置。5. 监控与告警虽然Supervisor能自动重启但频繁重启可能意味着程序有深层次问题。你可以结合其他监控工具如Prometheus Node Exporter或者简单的crontab脚本来监控Supervisor管理的进程状态并在异常时发送告警邮件、钉钉、Slack等。例如写一个脚本定期检查supervisorctl status的输出如果发现进程不是RUNNING状态就触发告警。Supervisor就像一位不知疲倦的哨兵默默守护着你的后台服务。从简单的脚本到复杂的Web应用集群它都能提供坚实的进程生命周期管理保障。花点时间掌握它能让你从繁琐的进程维护工作中解放出来把精力更多地投入到业务开发本身。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2411978.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!