我们想让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")
}
运行
我们只要在终端执行 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"
这个时候终端的io输出就会重定向到nohup.out 即当前目录的nohup.out 文件中,并返回进程号,我们看下当前目录 并查看一下进程号
查看当前目录
查看 nohup.out文件
明显的看到输出都写入到该文件中了
我们查看一下进程号
从而实现了守护进程,一切看起来好像很完美了
但是仍然有几个问题需要处理
问题一 服务器重启了怎么办
问题二 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这个进程号上 我们访问一下
是可以正确访问的
查看下3328这个进程的情况
完成
更多有关于supervisor 请移步至http://www.supervisord.org/