古之立大事者,不惟有超世之才,亦必有坚忍不拔之志。

Linux/Unix进程管理工具 ——Supervisor

运维开发 admin 105℃ 0评论

日常开发和运维场景中,有些应用进程我们希望它能在后台稳定运行,不要意外崩溃,而如果万一发生异常崩溃也能自动重启,保证运行的稳定,典型的需求场景如celery任务、Web服务等。今天我们就来介绍一下这种需求的解决方案,即守护进程,重点介绍一下Supervisor这一进程管理神器。

认识守护进程

关于进程的相关知识这里不再展开表述,各位同学可以回顾一下操作系统相关的内容,也可以参考这篇文章

守护进程的概念

在Linux或者Unix操作系统中,守护进程(Daemon)是一种运行在后台的特殊进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。由于在Linux中,每个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端被称为这些进程的控制终端,当控制终端被关闭的时候,相应的进程都会自动关闭。但是守护进程却能突破这种限制,它脱离于终端并且在后台运行,并且它脱离终端的目的是为了避免进程在运行的过程中的信息在任何终端中显示并且进程也不会被任何终端所产生的终端信息所打断。它从被执行的时候开始运转,直到整个系统关闭才退出。

前台任务和后台任务

要创建守护进程首先要让进程转变为后台任务,区别于常见命令行中的前台任务是独占命令行窗口,只有在运行完毕或手动终止才可以继续执行其他命令,后台任务创建后,用户还可以继续输入其他命令。

后台任务具有以下特点:

  • 不再继承当前session(对话)的标准输入(stdin),无法向该任务继续输入指令,如果它试图读取标准输入,就好暂停执行(halt),这一点是后台任务和前台任务的本质区别;
  • 继承当前session(对话)的标准输出(stdout)和标准错误(stderr),所以该后台任务的输出信息依然会同步地在命令行中显示,你可以把这些信息重定向到文件中作为日志;

将前台任务转化为后台任务的方法是在命令的尾部添加“&”符号,示例如下:

后台任务到守护进程:SIGHUP信号和标准 I/O

后台任务能否成为守护进程,或用户退出当前session后后台任务是否可以继续运行,这个问题要根据Linux系统的设计来看:

  1. 用户准备退出 session;
  2. 系统向该 session 发出 SIGHUP 信号;
  3. session 收到 SIGHUP信号发送给所以子进程;
  4. 子进程收到 SIGHUP 信号后,自动退出;

不难看出,因为这样的设计,前台任务在 session 退出时因为收到 SIGHUP 信号必然会退出。而后台任务是否收到 SIGHUP 信号取决于 Shell 的 huponexit 参数。我们可以通过以下命令查看 hoponexit 参数的值:

大多数Linux系统,这个参数都是默认关闭的,即“huponexit off”。因此,session退出时,SIGHUP 信号并不会发送给后台任务,所以一般后台任务并不会随着session一起退出。

假设 huponexit 参数是关闭的(开启的解决方案我们下面讨论 ),还有一个问题就是退出 session 后,如果后台进程与标准 I/O 有交互还是会挂掉,原因在于后台任务的标准 I/O 继承自当前 session,一旦后台任务读写标准 I/O,就会发现已经不存在了,所以报错终止运行。

解决方法就是对后台任务的标准 I/O 进行重定向:

创建守护进程的方法

如上文介绍,我们可以通过将前台任务转为后台任务来创建守护进程,但是这种方法并不保险,因为有的系统 huponexit 参数可能是开启的(on)。这里我们来介绍几种常见的创建守护进程的方法:

disown 命令

disown命令可以将制定任务从后台任务列表(jobs命令返回的结果)中移除,后台任务只要不在这个列表中,session就肯定不会向它发送 SIGHUP 信号了。使用方法如下:

disown的用法如下:

nohup 命令

nohup是比 disown 更为方便的命令,也是大家用的比较多的方式,方法如下:

nohup的原理是阻止 SIGHUP 信号发送到该进程;关闭标准输入,使得该进程不再能够接收任何输入,即使运行在前台;重定向标准输出和标准错误到文件 nohup.out 中。不难看出,nohup命令实际上是将子进程和它所在的 session 分离了。

使用terminal multiplexer( 终端复用器 )

不同于上面的两种方式,终端复用器是在同一个终端中管理多个session,常用的是Screen命令和Tmux命令。它们可以在当前session中新建另一个session,一旦当前session结束,并不影响其他session,同时以后重新登录,还可以再次连接早先新建的session。

Screen命令

Screen的使用方法如下:

Tmux命令

Tmux命令比Screen功能更多,更强大,使用方法如下:

Systemd

Linux系统有自己的守护进程管理工具Systemd,它是操作系统的部分,直接与内核交互,性能出色,功能极其强大。我们可以将程序交给Systemd,让系统统一管理,成为真正意义上的系统服务,当然这是最最推荐的方式。这里不展开讲了,参考文章

Node 应用专用工具

对于Node应用来说,可以使用专门的工具: forevernodemon 和 pm2

Daemontools & supervise

supervise来管理常驻进程。基于supervise的两个比较重要的工具是Daemontools和Supervisor。实际上,supervise也算Daemontools的一个工具。Daemontools是一个包含了很多管理Unix服务的工具的软件包, 是svscanboot,svscan,supervise,svc,svok,svstat等一系列工具的合集。Daemontools最经典的搭配是和lighttpd一起使用 ,其中最核心的工具是supervise,它的功能是监控一个指定的服务,当该服务进程消亡,则重新启动该进程。

要添加让supervise监控的服务非常容易,只需要添加一个被监控的服务的目录,在该目录中添加启动服务器的名字为run的脚本文件即可。supervisor是所有项目的父进程:supervisor(pid=29208)会成为主进程,管理各个项目的进程。当项目A(pid=11531)挂掉,supervisor根据设置autorestart、startretries是否重启。若要重启,则会重启项目A(pid=13357),若不重启,则项目A(pid=0)。当supervisor被kill,管理的项目全部死掉,重启supervisor(pid=14140),管理的项目都重启。

其他工具

  • monit;
  • runit ;
  • mini supervisor;
  • Mozilla的circus (已停止更新);
  • setsid;
  • runnit;
  • Ruby编写的God
  • debian系统的 upstart ;
  • start-stop-daemon;
  • 自己撸一个监控重启服务的程序;
  • crontab定时重启服务;

进程管理工具Supervisor

要说当前最为主流的进程管理工具,或者说最推荐的工具,当然是Supervisor了。作为一款实用Python编写的工具,Supervisor可以很方便的监听、启动、停止、重启一个或多个进程,采用C/S架构,支持Linux/Unix系统,不支持Windows系统。使用Superviosr管理的进程,在意外崩溃后,Supervisor监听到会自动将其拉起,极其方便的实现了进程的自动恢复,保证了服务的稳定可靠,让我们解放双手,不再依赖手写shell脚本了,是每位Pythoner的骄傲。

下面简单介绍一下Supervisor的使用:

安装Supervisor

由于Supervisor使用Python开发,所以安装非常方便:

Supervisor安装后会生成三个执行程序:supervisortd、supervisorctl、echo_supervisord_conf, 分别是supervisor的守护进程服务(用于接收进程管理命令)、客户端(用于和守护进程通信,发送管理进程的指令)、生成初始配置文件程序。

Supervisor配置

Supervisor在运行时需要指定配置文件,如果没有指定,默认会在下面这些目录中查找:

一般我们需要自行配置,可以运行 echo_supervisord_conf 程序生成 supervisor的初始化配置文件:

生成的配置文件中各种配置参数可以参考官方文档

这里比较重要的是最下面的include,你可以在这里继续添加新的进程管理配置文件。可以把所有配置项都写到 supervisord.conf 文件里,但并不推荐这样做,而是通过 include 的方式把不同的程序(组)写到不同的配置文件里。以Tomcat进程为例,我们可以创建一个新的ini配置文件,并在include声明,文件内容可以包含以下基本信息:

启动Supervisor

安装好Supervisor并做好配置后,这时我们就可以运行Supervisor服务啦。运行方式很简单:

使用Supervisor做进程管理

supervisord启动后,我们可以通过supervisorctl客户端来管理进程,控制进程的启动、重启、停止、查看状态等,你可以通过“ supervisorctl help”来查看所有的命令:

当然你常用的命令一般就下面这些:

  • status:查看所有进程的状态;
  • reload:重新加载supervisor的配置文件,并重启所有进程;
  • reread:读取有更新(增加)的配置文件,不会启动新添加的程序,也不会重启任何程序
  • restart name:重启特定的程序;
  • stop name:停止特定的程序;
  • start name:启动特定的程序;
  • update:重启配置文件修改过的程序,配置没有改动的进程不会收到影响而重启;

Supervisor的WEB管理界面

出于安全考量,Supervisor默认配置并没有开启WEB管理界面,你可以通过修改supervisord.conf配置文件来打开http访问权限,将原配置:

修改为:

这个 web 后台使用 Basic Auth 的方式进行身份认证。除了单个进程的控制,还可以配置 group,进行分组管理。经常查看日志文件,包括 supervisord 的日志和各个 pragram 的日志文件,程序 crash 或抛出异常的信息一半会输出到 stderr,可以查看相应的日志文件来查找问题。

Supervisor自带的管理界面不满意的话,可以引入cesi来管理Supervisor集群,同事也可以管理集群。

参考文献

转载请注明:北凉柿子 » Linux/Unix进程管理工具 ——Supervisor

喜欢 (2)or分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址