supervisor 进程管理

我们想让linux跑一个项目,例如一个web项目,希望这个web项目以守护进程的模式一直在上面跑,即使重启服务器,发生了异常扔能安全运行,或者告知我们进程发生了异常,这个时候我们可以考虑Python编写的supervisor 进程管理

举个简单的例子,我们用gin起一个简单的http服务
代码

package main

import "github.com/gin-gonic/gin"
func main() {
    r := gin.Default()
    r.GET("/", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "hello",
        })
    })
    r.Run(":8080")
}

运行


image.png

我们只要在终端执行 go run main.go 就可以监听8080端口 提供http服务,但是 一旦按下ctrl + c 或者退出终端,我们的go进程就会退出

但是我们希望它能一直在后台跑,这个时候我们可以使用nohup xxx &的方式起一个守护进程
例如上面的go run main.go可以改进为

[root@localhost demo]# nohup go run main.go &
[1] 2922
[root@localhost demo]# nohup: 忽略输入并把输出追加到"nohup.out"

image.png

这个时候终端的io输出就会重定向到nohup.out 即当前目录的nohup.out 文件中,并返回进程号,我们看下当前目录 并查看一下进程号
查看当前目录

image.png

查看 nohup.out文件


image.png

明显的看到输出都写入到该文件中了
我们查看一下进程号


image.png

从而实现了守护进程,一切看起来好像很完美了
但是仍然有几个问题需要处理
问题一 服务器重启了怎么办
问题二 nohup.out越来越大 不好管理
问题三 进程由于某些意外 被杀死 或者需要滑动重启怎么办
问题四 进程出现异常 我们不得而知 没有监控 无法管理

这个时候就需要引入我们的主角supervisor

Supervisor是用Python开发的一套通用的进程管理程序,
能将一个普通的命令行进程变为后台daemon,并监控进程状态,
异常退出时能自动重启。它是通过fork/exec的方式把这些被管理的进程当作supervisor的子进程来启动,
这样只要在supervisor的配置文件中,把要管理的进程的可执行文件的路径写进去即可。
也实现当子进程挂掉的时候,父进程可以准确获取子进程挂掉的信息的,可以选择是否自己启动和报警。

安装
yum install supervisor -y

安装完成后
配置文件的目录位于:
/etc/supervisord.conf 主配置文件
/etc/supervisor.d/ 默认子进程配置文件,我们的开头的web进程就可以放这里了
supervisord.conf 基本配置项说明
前面带有;则表示注释 跟nginx配置文件的#一个意思

[unix_http_server]
file=/home/supervisor/supervisor.sock   ; supervisorctl使用的 socket文件的路径
;chmod=0700                 ; 默认的socket文件权限0700
;chown=nobody:nogroup       ; socket文件的拥有者

[inet_http_server]         ; 提供web管理后台管理相关配置
port=0.0.0.0:9001          ; web管理后台运行的ip地址及端口,绑定外网需考虑安全性 
;username=root             ; web管理后台登录用户名密码
;password=root

[supervisord]
logfile=/var/log/supervisord.log ; 日志文件,默认在$CWD/supervisord.log
logfile_maxbytes=50MB        ; 日志限制大小,超过会生成新文件,0表示不限制
logfile_backups=10           ; 日志备份数量默认10,0表示不备份
loglevel=info                ; 日志级别
pidfile=/home/supervisor/supervisord.pid ; supervisord pidfile; default supervisord.pid              ; pid文件
nodaemon=false               ; 是否在前台启动,默认后台启动false
minfds=1024                  ; 可以打开文件描述符最小值
minprocs=200                 ; 可以打开的进程最小值

[supervisorctl]
serverurl=unix:///home/supervisor/supervisor.sock ; 通过socket连接supervisord,路径与unix_http_server->file配置的一致

[include]
files = supervisor.d/*.ini;指定了在当前目录supervisor.d文件夹下配置多个配置文件,跟nginx的 vhost/*一个意思

我们在/etc/supervisord.d/ 下定义一个goboot.ini文件

[program:goboot]                    ;这里的xxx是指的项目名字
directory = /mnt/hgfs/project/demo  ;程序所在目录
command =  go run main.go           ;程序启动命令
autostart=true                      ;是否跟随supervisord的启动而启动
autorestart=true                    ;程序退出后自动重启,可选值:[unexpected,true,false],默认为unexpected,表示进程意外杀死后才重启
stopasgroup=true                    ;进程被杀死时,是否向这个进程组发送stop信号,包括子进程
killasgroup=true                    ;向进程组发送kill信号,包括子进程
stdout_logfile=/home/wwwlogs/go.log ;该程序日志输出文件,目录需要手动创建
stdout_logfile_maxbytes = 50MB      ;日志大小
stdout_logfile_backups  = 100       ;备份数

定好后之后 我们开始启动,一下是启动命令 如果后面不跟着具体的program则是操作全局

  supervisorctl start all
  supervisorctl stop all
  supervisorctl restart all

如果想只操作具体的program 怎可以使用以下命令,我的goboot为例

  supervisorctl start goboot
  supervisorctl stop goboot
  supervisorctl restart goboot

先查看supervisord服务是否已经启动

[root@localhost wwwlogs]# service supervisord status
Redirecting to /bin/systemctl status supervisord.service
● supervisord.service - Process Monitoring and Control Daemon
   Loaded: loaded (/usr/lib/systemd/system/supervisord.service; disabled; vendor preset: disabled)
   Active: active (running) since 日 2021-03-21 15:53:23 CST; 5s ago
  Process: 3104 ExecStart=/usr/bin/supervisord -c /etc/supervisord.conf (code=exited, status=0/SUCCESS)
 Main PID: 3107 (supervisord)
   CGroup: /system.slice/supervisord.service
           └─3107 /usr/bin/python /usr/bin/supervisord -c /etc/supervisord.conf

3月 21 15:53:23 localhost.localdomain systemd[1]: Starting Process Monitoring and Control Daemon...
3月 21 15:53:23 localhost.localdomain systemd[1]: Started Process Monitoring and Control Daemon.

好了 现在可以启动我们的web项目了

[root@localhost supervisord.d]# supervisord -c /etc/supervisord.conf
Unlinking stale socket /var/run/supervisor/supervisor.sock
[root@localhost supervisord.d]# supervisorctl
goboot                           RUNNING   pid 3328, uptime 0:00:06

通过supervisorctl我们可以看到我们的项目启动在3328这个进程号上 我们访问一下


image.png

是可以正确访问的
查看下3328这个进程的情况


image.png

完成

更多有关于supervisor 请移步至http://www.supervisord.org/

你可能感兴趣的:(supervisor 进程管理)