后台需要持续运行这个二进制文件,保证服务的持续运行。
方案 1:
直接采用 nohup ./app_admin &后台运行方式,该方式存在一个缺点,如果服务器重启后,或者程序运行出错的话,服务就会终止,这种方式不稳定。
方案 2:
采用supervisor进程管理方式守护go语言的二进制文件运行,保证程序的持续运行。
Supervisor(http://supervisord.org/)是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,不支持Windows系统。它可以很方便的监听、启动、停止、重启一个或多个进程。用Supervisor管理的进程,当一个进程意外被杀死,supervisort监听到进程死后,会自动将它重新拉起,很方便的做到进程自动恢复的功能,不再需要自己写shell脚本来控制。
因为Supervisor是Python开发的,安装前先检查一下系统否安装了Python2.4以上版本
superviosr是一个Linux/Unix系统上的进程监控工具,他/她upervisor是一个Python开发的通用的进程管理程序,可以管理和监控Linux上面的进程,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。不过同daemontools一样,它不能监控daemon进程
supervisor管理进程,是通过fork/exec的方式将这些被管理的进程当作supervisor的子进程来启动,所以我们只需要将要管理进程的可执行文件的路径添加到supervisor的配置文件中就好了。此时被管理进程被视为supervisor的子进程,若该子进程异常中断,则父进程可以准确的获取子进程异常中断的信息,通过在配置文件中设置autostart=ture,可以实现对异常中断的子进程的自动重启。
安装supervisor
$ sudo apt-get install supervisor
配置文件
安装完supervisor后,输入以下命令可得到配置文件:
$ echo supervisord.conf
或者:
$ cat /etc/supervisord/supervisord.conf
配置文件用到几个部分:
[unix_http_server]:这部分设置HTTP服务器监听的UNIX domain socket
file: 指向UNIX domain socket,即file=/var/run/supervisor.sock
chmod:启动时改变supervisor.sock的权限
[supervisord]:与supervisord有关的全局配置需要在这部分设置
logfile: 指向记录supervisord进程的log文件
pidfile:pidfile保存子进程的路径
childlogdir:子进程log目录设为AUTO的log目录
[supervisorctl]:
serverurl:进入supervisord的URL, 对于UNIX domain sockets, 应设为 unix:///absolute/path/to/file.sock
[include]:如果配置文件包含该部分,则该部分必须包含一个files键:
files:包含一个或多个文件,这里包含了/etc/supervisor/conf.d/目录下所有的.conf文件,可以在该目录下增加我们自己的配置文件,在该配置文件中增加[program:x]部分,用来运行我们自己的程序,如下:
[program:x]:配置文件必须包括至少一个program,x是program名称,必须写上,不能为空
command:包含一个命令,当这个program启动时执行
directroy:执行子进程时supervisord暂时切换到该目录
user:账户名
startsecs:进程从STARING状态转换到RUNNING状态program所需要保持运行的时间(单位:秒)
redirect_stderr:如果是true,则进程的stderr输出被发送回其stdout文件描述符上的supervisord
stdout_logfile:将进程stdout输出到指定文件
stdout_logfile_maxbytes:stdout_logfile指定日志文件最大字节数,默认为50MB,可以加KB、MB或GB等单位
stdout_logfile_backups:要保存的stdout_logfile备份的数量
使用简单
supervisor提供了一种统一的方式来start、stop、monitor你的进程, 进程可以单独控制,也可以成组的控制。你可以在本地或者远程命令行或者web接口来配置Supervisor。
在linux下的很多程序通常都是一直运行着的,一般来说都需要自己编写一个能够实现进程start/stop/restart/reload功能的脚本,然后放到/etc/init.d/下面。但这样做也有很多弊端,第一我们要为每个程序编写一个类似脚本,第二,当这个进程挂掉的时候,linux不会自动重启它的,想要自动重启的话,我们还要自己写一个监控重启脚本。
而supervisor则可以完美的解决这些问题。supervisor管理进程,就是通过fork/exec的方式把这些被管理的进程,当作supervisor的子进程来启动。这样的话,我们只要在supervisor的配置文件中,把要管理的进程的可执行文件的路径写进去就OK了。第二,被管理进程作为supervisor的子进程,当子进程挂掉的时候,父进程可以准确获取子进程挂掉的信息的,所以当然也就可以对挂掉的子进程进行自动重启,当然重启还是不重启,也要看你的配置文件里面有木有设置autostart=true了。
supervisor通过INI格式配置文件进行配置,很容易掌握,它为每个进程提供了很多配置选项,可以使你很容易的重启进程或者自动的轮转日志。
集中管理
supervisor管理的进程,进程组信息,全部都写在一个ini格式的文件里就OK了。而且,我们管理supervisor的时候的可以在本地进行管理,也可以远程管理,而且supervisor提供了一个web界面,我们可以在web界面上监控,管理进程。 当然了,本地,远程和web管理的时候,需要调用supervisor的xml_rpc接口,这个也是后话。
supervisor可以对进程组统一管理,也就是说咱们可以把需要管理的进程写到一个组里面,然后我们把这个组作为一个对象进行管理,如启动,停止,重启等等操作。而linux系统则是没有这种功能的,我们想要停止一个进程,只能一个一个的去停止,要么就自己写个脚本去批量停止。
supervisor组件
supervisord
主进程,负责管理进程的server,它会根据配置文件创建指定数量的应用程序的子进程,管理子进程的整个生命周期,对crash的进程重启,对进程变化发送事件通知等。同时内置web server和XML-RPC Interface,轻松实现进程管理。。该服务的配置文件在/etc/supervisor/supervisord.conf。
supervisorctl
客户端的命令行工具,提供一个类似shell的操作接口,通过它你可以连接到不同的supervisord进程上来管理它们各自的子程序,命令通过UNIX socket或者TCP来和服务通讯。用户通过命令行发送消息给supervisord,可以查看进程状态,加载配置文件,启停进程,查看进程标准输出和错误输出,远程操作等。服务端也可以要求客户端提供身份验证之后才能进行操作。
Web Server
superviosr提供了web server功能,可通过web控制进程(需要设置[inethttpserver]配置项)。
XML-RPC Interface
XML-RPC接口, 就像HTTP提供WEB UI一样,用来控制supervisor和由它运行的程序。
安装、配置、使用
supervisor是python编写的,可以用easy_install、pip都可以安装,比如在我的centos机器下,安装命令如下:
yum install python-setuptools
easy_install pip
pip install superviso
设置配置文件。
echo_supervisord_conf > /etc/supervisord.conf
###为了不将所有新增配置信息全写在一个配置文件里,这里新建一个文件夹,每个程序设置一个配置文件,相互隔离
mkdir /etc/supervisord.d/
vim /etc/supervisord.conf
[include]
files = /etc/supervisord.d/*.conf
[inet_http_server]
port=9001
username=user
password=123
启动supervisord
# supervisord -c /etc/supervisord.conf
查看一下是否监听
# lsof -i:9001
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
superviso 14685 root 4u IPv4 20155719 0t0 TCP *:etlservicemgr (LISTEN)
现在通过 http://ip:9001/ 就可以查看supervisor的web界面了(默认用户名及密码是user和123),当然目前还没有加入任何监控的程序。
supervisor只能监控前台程序, 如果你的程序是通过fork方式实现的daemon服务,则不能用它监控,否则supervisor> status 会提示:BACKOFF Exited too quickly (process log may have details)。 因此像apache、tomcat服务默认启动都是按daemon方式启动的,则不能通过supervisor直接运行启动脚本(service httpd start),相反要通过一个包装过的启停脚本来完成,比如tomcat在supervisor下的启停脚本请参考:Controlling tomcat with supervisor或者supervisor-tomcat.conf。
另外,可以将supervisor随系统启动而启动,Linux 在启动的时候会执行 /etc/rc.local 里面的脚本,所以只要在这里添加执行命令即可:
/usr/local/bin/supervisord -c /etc/supervisord.conf
/usr/bin/supervisord -c /etc/supervisord.conf
default commands (type help
=====================================
add exit open reload restart start tail
avail fg pid remove shutdown status update
clear maintail quit reread signal stop version
test_http RUNNING pid 28087, uptime 0:05:17
其中
update 更新新的配置到supervisord(不会重启原来已运行的程序)
reload,载入所有配置文件,并按新的配置启动、管理所有进程(会重启原来已运行的程序)
start xxx: 启动某个进程
restart xxx: 重启某个进程
stop xxx: 停止某一个进程(xxx),xxx为[program:theprogramname]里配置的值
stop groupworker: 重启所有属于名为groupworker这个分组的进程(start,restart同理)
stop all,停止全部进程,注:start、restart、stop都不会载入最新的配置文
reread,当一个服务由自动启动修改为手动启动时执行一下就ok
注意:如果原来的程序启动时需要带上参数,那通过supervisorctl start时应该先写一个shell脚本,然后supervisorctl运行该脚本即可。
unixhttpserver配置块
在该配置块的参数项表示的是一个监听在socket上的HTTP server,如果[unixhttpserver]块不在配置文件中或被注释,则不会启动基于socket的HTTP server。该块的参数介绍如下:
password:认证密码
inethttpserver配置块
在该配置块的参数项表示的是一个监听在TCP上的HTTP server,如果[inethttpserver]块不在配置文件中或被注释,则不会启动基于TCP的HTTP server。该块的参数介绍如下:
[inet_http_server] ; inet (TCP) server disabled by default
port=0.0.0.0:9001 ; (ip_address:port specifier, *:port for all iface)
username=user ; (default is no username (open server))
password=123 ; (default is no password (open server))
表示监听在9001端口,需要使用用户名+密码的方式访问,访问地址是:http//127.0.0.1:9001。
supervisord配置块
该配置块的参数项是关于supervisord进程的全局配置项。该块的参数介绍如下:
program配置块
该块就是我们要监控的程序的配置项。该配置块的头部是有固定格式的,一个关键字program,后面跟着一个冒号,接下来才是程序名。例如:[program:foo],foo就是程序名,在使用supervisorctl来操作程序的时候,就是以foo来标明的。该块的参数介绍如下:
[program:test_http]
command=python test_http.py 10000 ; 被监控的进程启动命令
directory=/root/ ; 执行前要不要先cd到目录去,一般不用
priority=1 ;数字越高,优先级越高
numprocs=1 ; 启动几个进程
autostart=true ; 随着supervisord的启动而启动
autorestart=true ; 自动重启。。当然要选上了
startretries=10 ; 启动失败时的最多重试次数
exitcodes=0 ; 正常退出代码(是说退出代码是这个时就不再重启了吗?待确定)
stopsignal=KILL ; 用来杀死进程的信号
stopwaitsecs=10 ; 发送SIGKILL前的等待时间
redirect_stderr=true ; 重定向stderr到stdout
不过由于supervisor本身支持xml-rpc,因此也有一些基于supervisor二次开发的多机器进程管理工具。比如:
Django-Dashvisor
Web-based dashboard written in Python. Requires Django 1.3 or 1.4.
Nodervisor
Web-based dashboard written in Node.js.
Supervisord-Monitor
Web-based dashboard written in PHP.
SupervisorUI
Another Web-based dashboard written in PHP.
cesi
cesi is a web interface provides manage supervizors from same interface.