美文网首页
Supervisor的安装和入门

Supervisor的安装和入门

作者: Lension | 来源:发表于2019-10-04 14:20 被阅读0次

    前几天准备部署一个go应用,由于目前go的daemon方案还不完善,只能借助其他工具进行部署,所以发现了一个非常好用的进程管理工具——Supervisor。

    Supervisor(http://supervisord.org/)是用Python实现的一款非常实用的进程管理工具。supervisor会帮你把管理的应用程序转成daemon程序,而且可以方便的通过命令开启、关闭、重启等操作,而且它管理的进程一旦崩溃会自动重启,这样就可以保证程序执行中断后的情况下有自我修复的功能。

    本文将介绍如何在CentOS上Supervisor的安装和使用。

    1 安装

    1.1 安装环境

    可以先运行以下命令看系统是否安装了python,以及python的版本

    [root@192 ~]# python -V

    image

    Supervisor需要的python版本是python2 2.4以上(暂未明确是否支持python3)

    如果系统没有安装python2的话,可以使用系统自带安装工具安装python2

    [root@192 ~]# yum install python2

    再安装python包管理工具easy_install

    [root@192 ~]# yum install python-setuptools

    1.2 安装supervisor

    使用easy_install安装supervisor

    [root@192 ~]# easy_install supervisor

    验证是否安装成功

    [root@192 ~]# supervisord -v

    image

    注意:supervisor的命令是supervisord,命令比名称多一个d

    supervisor主要是两个命令:

    1. supervisord是主进程命令,用于启动supervisor

    2. supervisorctl是管理命令,用于管理supervisor中的应用程序

    2 配置

    2.1 配置文件

    执行如下命令

    [root@192 ~]# echo_supervisord_conf

    我们可以看到一份标准的配置文件模板

    下面简单说明(翻译)一下这份模板

    [unix_http_server]
    file=/tmp/supervisor.sock   ; UNIX socket文件默认路径,supervisorctl命令会使用到。
    ;chmod=0700                 ; socket file mode (default 0700)
    ;chown=nobody:nogroup       ; socket file uid:gid owner
    ;username=user              ; default is no username (open server)
    ;password=123               ; default is no password (open server)
    
    ;[inet_http_server]         ; HTTP服务器,提供Web UI管理界面。默认不开启。
    ;port=127.0.0.1:9001        ; Web管理后台运行的IP和端口,如果开放到公网上需注意安全性。
    ;username=user              ; Web管理后台登录的用户名
    ;password=123               ; Web管理后台登录的密码
    
    [supervisord]
    logfile=/tmp/supervisord.log ; 主进程的日志文件路径,默认为当前路径下的supervisord.log即$CWD/supervisord.log
    logfile_maxbytes=50MB        ; max main logfile bytes b4 rotation; default 50MB
    logfile_backups=10           ; # of main logfile backups; 0 means none, default 10
    loglevel=info                ; log level; default info; others: debug,warn,trace
    pidfile=/tmp/supervisord.pid ; 主进程编号文件,默认文件名为supervisord.pid
    nodaemon=false               ;主进程是否在前台启动,默认false即以守护进程daemon的方式在后台运行。
    minfds=1024                  ; 主进程可以打开的文件描述符的最小数量,默认为1024。
    minprocs=200                 ; 主进程可以打开的进程最小数量,默认为200。
    ;umask=022                   ; process file creation umask; default 022
    ;user=supervisord            ; setuid to this UNIX account at startup; recommended if root
    ;identifier=supervisor       ; supervisord identifier, default is 'supervisor'
    ;directory=/tmp              ; default is not to cd during start
    ;nocleanup=true              ; don't clean up tempfiles at start; default false
    ;childlogdir=/tmp            ; 'AUTO' child log dir, default $TEMP
    ;environment=KEY="value"     ; key value pairs to add to environment
    ;strip_ansi=false            ; strip ansi escape codes in logs; def. false
    
    [rpcinterface:supervisor]
    supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
    
    [supervisorctl]      
    serverurl=unix:///tmp/supervisor.sock ; 通过UNIX socket连接supervisord主进程,路径与unix_http_server部分的file一致。
    ;serverurl=http://127.0.0.1:9001 ; 使用HTTP方式连接supervisord主进程
    ;username=chris              ; should be same as in [*_http_server] if set
    ;password=123                ; should be same as in [*_http_server] if set
    ;prompt=mysupervisor         ; cmd line prompt (default "supervisor")
    ;history_file=~/.sc_history  ; use readline history if available
    
    ;[program:theprogramname]     ; 被管理的进程的配置参数,theprogramname表示进程的名字。
    ;command=/bin/cat              ; 程序启动命令的路径
    ;process_name=%(program_name)s ; 用来表示supervisor进程启动时的名字,是一个Python字符串表达式,默认为%(program_name)s。
    ;numprocs=1                    ; 启动的进程实例数
    ;directory=/tmp                ; 进程运行目录
    ;umask=022                     ; umask for process (default None)
    ;priority=999                  ; 进程启动优先级,默认999,值越小越优先启动。控制程序启动和关闭的顺序,越早启动越晚关闭。
    ;autostart=true                ; 在supervisord主进程启动时此程序自动启动
    ;startsecs=1                   ; 启动1秒后没有异常退出则表示进程正常运行
    ;startretries=3                ; 启动失败时自动重试次数,默认为3次。
    ;autorestart=unexpected        ;程序退出后自动重启,可选值为unexpected/true/false,unexpected表示进程意外杀死后才重启。
    ;exitcodes=0                   ; 自动重启预设的退出返回码,默认为0。
    ;stopsignal=QUIT               ; 当收到stop请求时发送信号给程序,默认为TERM,可选值HUP/INT/QUIT/KILL/USR1/USR2
    ;stopwaitsecs=10               ; 操作系统给主进程发送SIGCHILD信号时等待的时长
    ;stopasgroup=false             ; send stop signal to the UNIX process group (default false)
    ;killasgroup=false             ; SIGKILL the UNIX process group (def false)
    ;user=chrism                   ; setuid to this UNIX account to run the program
    ;redirect_stderr=true          ; redirect proc stderr to stdout (default false)
    ;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO
    ;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
    ;stdout_logfile_backups=10     ; # of stdout logfile backups (0 means none, default 10)
    ;stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
    ;stdout_events_enabled=false   ; emit events on stdout writes (default false)
    ;stdout_syslog=false           ; send stdout to syslog with process name (default false)
    ;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO
    ;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
    ;stderr_logfile_backups=10     ; # of stderr logfile backups (0 means none, default 10)
    ;stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
    ;stderr_events_enabled=false   ; emit events on stderr writes (default false)
    ;stderr_syslog=false           ; send stderr to syslog with process name (default false)
    ;environment=A="1",B="2"       ; process environment additions (def no adds)
    ;serverurl=AUTO                ; override serverurl computation (childutils)
    
    ;[eventlistener:theeventlistenername]
    ;command=/bin/eventlistener    ; the program (relative uses PATH, can take args)
    ;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
    ;numprocs=1                    ; number of processes copies to start (def 1)
    ;events=EVENT                  ; event notif. types to subscribe to (req'd)
    ;buffer_size=10                ; event buffer queue size (default 10)
    ;directory=/tmp                ; directory to cwd to before exec (def no cwd)
    ;umask=022                     ; umask for process (default None)
    ;priority=-1                   ; the relative start priority (default -1)
    ;autostart=true                ; start at supervisord start (default: true)
    ;startsecs=1                   ; # of secs prog must stay up to be running (def. 1)
    ;startretries=3                ; max # of serial start failures when starting (default 3)
    ;autorestart=unexpected        ; autorestart if exited after running (def: unexpected)
    ;exitcodes=0                   ; 'expected' exit codes used with autorestart (default 0)
    ;stopsignal=QUIT               ; signal used to kill process (default TERM)
    ;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
    ;stopasgroup=false             ; send stop signal to the UNIX process group (default false)
    ;killasgroup=false             ; SIGKILL the UNIX process group (def false)
    ;user=chrism                   ; setuid to this UNIX account to run the program
    ;redirect_stderr=false         ; redirect_stderr=true is not allowed for eventlisteners
    ;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO
    ;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
    ;stdout_logfile_backups=10     ; # of stdout logfile backups (0 means none, default 10)
    ;stdout_events_enabled=false   ; emit events on stdout writes (default false)
    ;stdout_syslog=false           ; send stdout to syslog with process name (default false)
    ;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO
    ;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
    ;stderr_logfile_backups=10     ; # of stderr logfile backups (0 means none, default 10)
    ;stderr_events_enabled=false   ; emit events on stderr writes (default false)
    ;stderr_syslog=false           ; send stderr to syslog with process name (default false)
    ;environment=A="1",B="2"       ; process environment additions
    ;serverurl=AUTO                ; override serverurl computation (childutils)
    
    ;[group:thegroupname]          ; 组服务
    ;programs=progname1,progname2  ; 配置多个服务的名称
    ;priority=999                  ; 启动优先级,默认999。
    
    ;[include]                     ; 包含配置文件
    ;files = relative/directory/*.ini
    
    

    这个配置文件包含了supervisor主进程配置和应用程序(我们希望被管理的程序)配置,一般推荐将主程序配置和应用程序配置分开配置。

    2.1 配置

    配置文件里面默认将很多文件放置到/tmp/下,但是有时候系统会自动清理该目录的文件,导致supervisor无故挂掉或者控制不了,所以我们需要先创建几个目录来存放文件

    首先,推荐创建/etc/supervisord.d/来放置应用程序的配置

    然后,推荐创建/var/supervisord/来放置sock和pid文件

    最后,推荐创建/var/supervisord/log/来放置日志文件

    下面的操作都是以这几个路径来配置

    2.1.1 创建主进程配置文件

    生成主进程配置文件

    [root@192 ~]# echo_supervisord_conf > /etc/supervisord.conf

    注意:主配置文件请以这个名称放在这个目录,如果放在其他地方请创建一个软连接,否则supervisorctl将无法管理应用程序

    下面讲一些需要修改的地方,不需要修改的保持原样即可

    [unix_http_server]
    file=/var/supervisord/supervisor.sock   ; sock文件
    ..
    ..
    
    ;[inet_http_server]         ; 出于安全考虑这个模块一般情况不开启
    ..
    ..
    
    [supervisord]
    logfile=/var/supervisord/log/supervisord.log ; 主进程log文件
    ..
    ..
    pidfile=/var/supervisord/supervisord.pid ; pid文件
    ..
    ..
    childlogdir=/var/supervisord/log            ; 应用程序日志文件
    ..
    ..
    
    [rpcinterface:supervisor]
    ..
    ..
    
    [supervisorctl]
    serverurl=unix:///var/supervisord/supervisor.sock ; 读取主进程sock文件
    ..
    ..
    
    ;[program:theprogramname]      ; 这个模块是应用程序配置,在主进程中可以删除或者不管
    ..
    ..
    
    ;[eventlistener:theeventlistenername]  ;这个模块在主进程中可以删除或者不管
    ..
    ..
    
    ;[group:thegroupname]
    ..
    ..
    
    [include]                            ; 把这个模块前面的';'去掉,启用这个模块
    files = /etc/supervisord.d/*.ini     ; 应用程序配置目录
    
    
    2.1.2 创建应用程序文件

    首先,在/etc/supervisord.d/创建一个ini文件

    [root@192 ~]# vim /etc/supervisord.d/demo.ini

    然后把[program:theprogramname]模块整个拷贝进去

    同样,讲一些需要修改的地方

    [program:demo_cat]             ; 名称很重要,涉及后面的管理
    command=/bin/cat              ; 应用程序的路径,以cat为例子
    ..
    ..
    directory=/tmp               ; 应用程序的运行目录。如果应用程序涉及相对路径的文件,这个一定要修改好
    ..
    ..
    autostart=true                ; start at supervisord start (default: true)
    startsecs=5                   ; 设置得太低可能会因为没来得及启动被判启动失败
    startretries=3                ; max # of serial start failures when starting (default 3)
    autorestart=true        ; when to restart if exited after running (def: unexpected)
    ..
    ..
    stopasgroup=true             ; send stop signal to the UNIX process group (default false)
    killasgroup=true             ; SIGKILL the UNIX process group (def false)
    ..
    ..
    ..
    
    

    这样就配置完成了

    3 启动

    3.1 启动supervisor

    [root@192 ~]# supervisord -c /etc/supervisord.conf

    使用该命令启动supervisor

    查看是否启动成功

    [root@192 ~]# supervisorctl status

    image

    可以看到,我们刚才配置的demo_cat程序已经在运行了

    3.2 管理应用程序

    主要是通过supervisorctl来管理应用程序

    supervisorctl status                 // 查看所有应用程序状态
    supervisorctl stop programxxx        // 停止某个应用程序
    supervisorctl start programxxx       // 启动某个应用程序
    supervisorctl restart programxxx     // 重启某个应用程序
    supervisorctl stop all               // 停止所有应用程序
    supervisorctl reread                 // 读取有更新(增加)的配置文件,不会启动新添加的程序
    supervisorctl update                 // 更新配置文件变化并重启变化的服务
    supervisorctl reload                 // 更新配置并重启supervisor
    supervisorctl shutdown               // 停止supervisor
    supervisorctl tail programxxx stdout // 查看某个应用程序的输出
    

    同时,根据上面的配置,supervisor会重定向应用程序的输出,并保存到/var/supervisord/log里面

    image

    3.3 supervisor开机自启动

    新建开机启动服务

    [root@192 ~]# vim /lib/systemd/system/supervisord.service

    在supervisord.service中添加以下内容:

    # supervisord service for systemd (CentOS 7.0+)
    # by ET-CS (https://github.com/ET-CS)
    [Unit]
    Description=Supervisor daemon
    [Service]
    Type=forking
    ExecStart=/usr/bin/supervisord
    ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown
    ExecReload=/usr/bin/supervisorctl $OPTIONS reload
    KillMode=process
    Restart=on-failure
    RestartSec=42s
    [Install]
    WantedBy=multi-user.target
    

    将服务脚本添加到systemctl自启动服务:

    [root@192 ~]# systemctl enable supervisord.service

    重启系统测试开机启动。

    4 可能遇到的问题

    4.1 error: <class 'socket.error'>, [Errno 113] No route to host: file: /usr/lib64/python2.7/socket.py line: 571

    这个问题网上很多人说是防火墙问题,他们的解决办法都不适用。supervisor是本地服务,跟防火墙没有关系。后面我发现是因为supervisorctl默认在/etc/里面有supervisord.conf。所以如果你的/etc/里面没有supervisord.conf,建议你建个软连接,把主程序配置文件连接过来。例如:

    [root@192 ~]# ln -s /etc/supervisord.conf /etc/supervisord.conf

    4.2 error: <class 'socket.error'>, [Errno 111] Connection refused: file: /usr/lib64/python2.7/socket.py line: 224

    这个问题是因为supervisor没有启动导致的。请确认superviosr是否已经启动。

    4.3 unix:///tmp/supervisor.sock no such file

    这个问题是因为sock文件不见了。sock文件被删除一般是因为放在默认的/tmp/里面被系统删除了。也有可能跟我一样,根据网上其他supervisor开机自启动的办法,将supervisrod.conf里面的nodaemon=false改成true,导致系统一直重启supervisor,sock文件也就会一直被删除和创建。

    5 更新

    本人也是新手,欢迎大家一起讨论学习。后面有新的学习经验和体会会进一步更新。


    参考链接

    1. https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/12.3.md
    2. https://blog.csdn.net/xyang81/article/details/51555473
    3. https://www.missshi.cn/api/view/blog/5aafcf405b925d681e000000
    4. https://blog.csdn.net/u012724150/article/details/54616600
    5. https://www.jianshu.com/p/3c70e12b656a
    6. https://blog.csdn.net/sinat_21302587/article/details/76836283
    7. http://wonse.info/centos7-supervisor-auto-start.html

    相关文章

      网友评论

          本文标题:Supervisor的安装和入门

          本文链接:https://www.haomeiwen.com/subject/rynjpctx.html