部署管理Swoole服务
{{moment(1499829638000).format('MMM DD, YYYY, h:mm')}}
PHP
PHP
Systemd
Swoole
Supervisor
使用Systemd管理Swoole服务
Systemd 是 Linux 系统工具,用来启动守护进程。
Systemd 并不是一个命令,而是一组命令,涉及到系统管理的方方面面。包括:systemctl,systemd-analyze,hostnamectl,localectl,timedatectl,loginctl
更多参考:Systemd介绍
所以Swoole的服务器程序可以编写一段service脚本,交由systemd进行管理。实现故障重启、开机自启动等功能。
使用systemd管理swoole服务参考文档:swoole官方文档
Demo:
在/etc/systemd/system/swoole_http.service新建一个service文件,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| [Unit] Description=Swoole Http service After=network.target After=syslog.target [Service] Type=forking PIDFile=/home/www/http/bin/server.pid ExecStart=/home/www/http/bin/server ExecStop=/bin/kill -15 $MAINPID ExecReload=/bin/kill -USR1 $MAINPID Restart=always [Install] WantedBy=multi-user.target graphical.target
|
需要注意的是$MAINPID必须要是manager的id,不然启动或者重启的时候会报错。而且还需要修改swoole配置参数,把swoole的守护进程化设置为daemonize => 1。
kill -USR1 pid 重启woker进程和task进程
kill -USR2 pid 重启task进程
kill -15 管理进程id 关掉所有的manager相关进程
关于swoole重启的文档:链接
使用Supervisor管理swoole服务
Supervisor是一个客户/服务器系统,它可以在类Unix系统中管理控制大量进程。Supervisor使用python开发,有多年历史,目前很多生产环境下的服务器都在使用Supervisor,部署python程序经常这个。
Supervisor的服务器端称为supervisord,主要负责在启动自身时启动管理的子进程,响应客户端的命令,重启崩溃或退出的子进程,记录子进程stdout和stderr输出,生成和处理子进程生命周期中的事件。可以在一个配置文件中配置相关参数,包括Supervisord自身的状态,其管理的各个子进程的相关属性。配置文件一般位于/etc/supervisord.conf。
Supervisor的客户端称为supervisorctl,它提供了一个类shell的接口(即命令行)来使用supervisord服务端提供的功能。通过supervisorctl,用户可以连接到supervisord服务器进程,获得服务器进程控制的子进程的状态,启动和停止子进程,获得正在运行的进程列表。客户端通过Unix域套接字或者TCP套接字与服务端进行通信,服务器端具有身份凭证认证机制,可以有效提升安全性。当客户端和服务器位于同一台机器上时,客户端与服务器共用同一个配置文件/etc/supervisord.conf,通过不同标签来区分两者的配置。
Supervisor也提供了一个web页面来查看和管理进程状态,这个功能非常酷.
安装Supervisor
1 2 3 4 5 6
| # 我们可以通过pypi安装 pip install supervisor # 或者从pypi上下载源码,然后安装 python setup.py install # 安装完之后,使用下列命令来生成配置文件 echo_supervisord_conf > /etc/supervisord.conf
|
1
| # mkdir /etc/supervisord.d 用户存放被监控进程的配置文件
|
修改/etc/supervisord.conf配置文件:
1 2 3 4
| 在文件结尾[include]节点处把 ;files = relative/directory/*.ini改为files =/etc/supervisord.d/*.conf 同时还需要去掉[include]前面的;
|
保存并退出。
把supervisor加入开机自启动服务
到systemd系统下新建一个service配置文件
1
| vim /lib/systemd/system/supervisor.service
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| [Unit] Description=supervisor After=network.target [Service] Type=forking ExecStart=/usr/bin/supervisord -c /etc/supervisord.conf ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown ExecReload=/usr/bin/supervisorctl $OPTIONS reload KillMode=process Restart=on-failure RestartSec=42s [Install] WantedBy=multi-user.target graphical.target
|
上述文件编写后,执行如下命令即可:
1
| systemctl enable supervisor.service
|
加入开机自启动服务
重新载入systemd,扫描新的或有变动的单元。
实际上supervisor已经加入了systemctl管理了,后续起停supervisor服务都可以通过systemctl来控制了。
1 2 3 4 5 6 7 8 9
| systemctl start supervisor.service 启动服务 systemctl stop supervisor.service 停止服务 systemctl restart supervisor.service 重新启动服务 systemctl reload supervisor.service 重载配置文件 systemctl status supervisor.service 查看服务状态
|
在/etc/supervisord.d 增加一个程序的demo配置参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| [program:cat] ;程序名 command=/bin/cat ;命令绝对路径,可以包含参数 process_name=%(program_name)s ;进程名 numprocs=1 ;supervisor启动多少个该程序,如果大于1,那么进程名必须包括%(process_num)s directory=/tmp ;该进程的启动时的工作目录 umask=022 ;掩码 priority=999 ;优先级 autostart=true ;该程序是否在supervisor启动时启动 autorestart=true ;如果为false,那么该程序的相关进程永远不会自动重启。如果为unexpected,该程序的相关进程仅会在退出码为exitcodes中的值时重启;如果为true时 startsecs=10 ;最大启动时间 startretries=3 ;最大启动重试次数。超过这个次数后,该进程会标记为FATAL状态 exitcodes=0,2 ;退出码,关联autorestart=unexpected stopsignal=TERM ;关闭该程序相关进程所发送的信号量。可以为TERM, HUP, INT, QUIT, KILL, USR1, or USR2 stopwaitsecs=10 ;supervisord父进程等待该程序的相关子进程返回SIGCLILD信号量的时间,超时后则发送SIGKILL user=chrism ;启动该程序进程的用户 redirect_stderr=false ;如果为true,则将该程序的进程错误输出到supervisor主日志文件中 stdout_logfile=/tmp ;标准输出 stdout_logfile_maxbytes=1MB ;日志轮滚 stdout_logfile_backups=10 ;日志轮滚 stdout_capture_maxbytes=1MB stderr_logfile=/a/path stderr_logfile_maxbytes=1MB stderr_logfile_backups=10 stderr_capture_maxbytes=1MB environment=A="1",B="2" ;!环境变量信息 serverurl=AUTO ;传送给该子进程的环境变量SUPERVISOR_SERVER_URL ,AUTO则自动提供一个Supervisord的URL。用于该进程可以和内部HTTP Server进行通信,简化进程管理。
|
从swoole的文档我们得知:
Swoole提供了柔性终止/重启的机制,管理员只需要向SwooleServer发送特定的信号,Server的worker进程可以安全的结束。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| SIGTERM: 向主进程/管理进程发送此信号服务器将安全终止 在PHP代码中可以调用$serv->shutdown()完成此操作 SIGUSR1: 向主进程/管理进程发送SIGUSR1信号,将平稳地restart所有worker进程 在PHP代码中可以调用$serv->reload()完成此操作 swoole的reload有保护机制,当一次reload正在进行时,收到新的重启信号会丢弃 如果设置了user/group,Worker进程可能没有权限向master进程发送信息,这种情况下必须使用root账户,在shell中执行kill指令进行重启 reload指令对addProcess添加的用户进程无效 #重启所有worker进程 kill -USR1 主进程PID #仅重启task进程 kill -USR2 主进程PID
|
supervisor的程序restart的原理是实际上是发信号,所以我们需要给swoole的程序stop信号配置为:stopsignal=TERM
同时还需要把swoole的守护进程化设置为daemonize => 0,不然会报spawned error
supervisorctl控制program
现在supervisor的server端我们已经交给systemd去管理,现在我们可以通过supervisorctl去控制配置添加的program
1 2 3 4 5 6 7
| supervisorctl -c supervisor.conf status 察看supervisor的状态 supervisorctl -c supervisor.conf reload 重新载入 配置文件 supervisorctl -c supervisor.conf start [all]|[appname] 启动指定/所有supervisor管理的程序进程 supervisorctl -c supervisor.conf stop [all]|[appname] 关闭指定/所有 supervisor管理的程序进程
|