在之前的一篇文章《终端自动化测试探索之路》中提到过当发生断电等情况,服务器重启之后如何快速恢复自动化服务,这里针对这个问题具体讲讲我的实现方式。
背景
自动化测试系统中涉及很多服务进程,比如appium server、http server、stf、还有用来管理服务器上挂载设备状态的agent等,如果出现断电等异常情况机器重启,那么这些服务将变的不可用,影响系统的整体稳定性。
方案选型
基于上述原因,我考虑采用supervisor来管理这些进程,supervisor是一个UNIX-like系统上的进程管理工具,是一个由Python开发的c/s系统,可以管理和监控unix上面的进程,不过它不能监控daemon进程。
1、部署简单
我们通常管理linux进程的时候,一般来说都需要自己编写一个能够实现进程start/stop/restart/reload功能的脚本,然后丢到/etc/init.d/下面,这么做有很多不好的地方:
那supervisor是如何实现进程管理并重启的呢?
supervisor管理的进程、进程组信息,全部都写在一个ini格式的文件里。而且我们管理supervisor的时候的可以在本地进行管理,也可以远程管理,而且supervisor提供了一个web界面,我们可以在web界面上监控、管理进程。
2、精准
使用supervisor监控子进程,得到的子进程状态无疑是准确的。
3、进程组
supervisor可以对进程组进行统一管理,也就是说我们可以把需要管理的进程写到一个组里面,然后把这个组作为一个对象进行管理,如启动、停止、重启等操作。而在linux系统上是没有这种功能的,我们想要停止一个进程,只能一个一个的去停止,要么就自己写个脚本去批量停止。
大家应该都知道linux的进程,特别是监听在1024端口之下的进程,一般用户大多数情况下是不能对其进行控制的。想要控制的话,必须要有root权限,而supervisor提供了一个功能,可以为supervisord或者每个子进程,设置一个非root的user,这个user就可以管理它对应的进程了。
supervisor的结构
supervisor主要由Supervisord、Supervisorctl、Web server和XML-RPC interface组成。
安装部署
由于我使用的服务器是Macmini,在Mac上安装supervisor可以使用brew:
brew install supervisor
使用
执行 supervisorctl 进入supervisor的命令行交互界面 > status # 查看程序状态 > stop program_name # 关闭 program_name 程序 > start program_name # 启动 program_name 程序 > restart program_name # 重启 program_name 程序 > reread # 读取有更新(增加)的配置文件,不会启动新添加的程序,也不会重启任何程序 > reload # 载入最新的配置文件,停止原有的进程并按照新的配置启动 > update # 重启配置文件修改过的程序,配置没有改动的进程不会收到影响而重启
开启 web 管理
文章头图就是supervisor的web管理页面。
vi /usr/local/etc/supervisord.ini# 将下面注释去掉 [inet_http_server] ; inet (TCP) server disabled by default port=127.0.0.1:9001 ; (ip_address:port specifier, *:port for all iface) username=root ; (default is no username (open server)) password=root ; (default is no password (open server))# 重启服务 $ brew services restart supervisor
进程管理
配置supervisord可以查看supervisord.ini的最后一行配置:
vim /usr/local/etc/supervisord.ini# [include] # files = /usr/local/etc/supervisor.d/*.ini
可以把配置文件写到/usr/local/etc/supervisor.d/目录下,只要以.ini后缀结尾就行,就拿appium server来说:
vi appium.ini[program:appium] directory=/Users/xxxxcommand=/usr/local/bin/appium --address 127.0.0.1 --port 4723 --log "log_path" --log-timestamp --local-timezone --session-overridenumprocs=1numprocs_start=0priority=999autostart=trueautorestart=truestartsecs=3startretries=3exitcodes=0,2stopwaitsecs=60user=rootenvironment=PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:stopasgroup=truekillasgroup=trueredirect_stderr=truestdout_logfile=/var/log/appium_out.logstderr_logfile=/var/log/appium_err.logstdout_logfile_maxbytes=100MBstdout_logfile_backups=10stderr_logfile_maxbytes=100MBstderr_logfile_backups=10loglevel=debug
这里有一点需要注意的是,当我们需要管理的进程中有用到adb等命令的时候要在上面配置文件中的environment这里配置一下系统的环境变量。
接下来重新载入配置文件,就可以通过上面的web管理页面管理进程了:
supervisorctl reload