CentOS7安装配置supervisor

之前一直用AWS的服务,使用的也是AWS官方提供的系统镜像,感觉挺好使的,所以centos7的版本用的不多。最近刚好需要使用腾讯云,记录一下supervisor的安装配置,不管简单与否,好久没写博客了还是记录一下吧。


安装

  • Env:

    • OS: CentOS Linux release 7.4.1708 (Core)
    • Python: Python 2.7.5
    • Pip: pip 8.1.2 from /usr/lib/python2.7/site-packages (python 2.7)
  • Install supervisor with pip

    1
    2
    3
    4
    5
    6
    7
    8
    yum install python-pip #8.1.2-6.el7
    pip install supervisor #meld3-1.0.2 supervisor-3.3.4
    supervisord -v
    #Install supervisor
    mkdir /etc/supervisor
    echo_supervisord_conf > /etc/supervisor/supervisord.conf
    cat /etc/supervisor/supervisord.conf |egrep -v "^$|^;"
    #Create supervisor config file
  • Support systemd

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    systemctl --version #systemd 219
    #Support systemd
    wget https://raw.githubusercontent.com/zokeber/supervisor-systemd/master/etc/systemd/system/supervisord.service -O /etc/systemd/system/supervisord.service
    #Download systemd config for supervisor.
    #https://github.com/Supervisor/initscripts
    systemctl status supervisord
    #Now can use systemctl command to manage supervisor service
    systemctl start supervisord #{start|stop|restart|reload}
    #Start service
    systemctl list-unit-files | grep supervisor
    #检查所有服务开机启动状态并过滤指定服务
    systemctl enable supervisord
    #添加服务到开机自启动
    systemctl is-enabled supervisord
    #查询指定服务开机启动状态
  • Tip: supervisord.service文件如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    [Unit]
    Description=Supervisor process control system for UNIX
    Documentation=http://supervisord.org
    After=network.target
    [Service]
    ExecStart=/usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
    ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown
    ExecReload=/usr/bin/supervisorctl $OPTIONS reload
    KillMode=process
    Restart=on-failure
    RestartSec=50s
    [Install]
    WantedBy=multi-user.target
  • Tip: 主配置/etc/supervisor/supervisord.conf示例(参考Flowsnow的博客及官方文档)附:我的配置】

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    [unix_http_server]
    file = /tmp/supervisor.sock ;socket文件路径
    ;chmod=0700 ; socket 文件 模式 (默认 0700)
    ;chown=nobody:nogroup ; socket file uid:gid owner
    ;username=user ; 使用supervisorctl连接的用户,默认没有用户
    ;password=123 ; 使用supervisorctl连接的用户密码,默认没有密码
    ;
    [inet_http_server]
    port = 172.21.0.4:9001 ;Web Server和远程的supervisorctl配置,默认关闭
    username = user123 ;登录用户,默认没有
    password = password123 ;用于登录密码,默认没有
    ;
    [supervisord]
    logfile = /tmp/supervisord.log ;supervisord进程的日志路径
    logfile_maxbytes = 100MB ;supervisor单个日志的大小,默认为50M
    logfile_backups = 20 ;日志文件的个数,默认为10
    loglevel = info ;日志级别,默认info {trace|info|warn|debug}
    pidfile = /tmp/supervisord.pid ;supervisor的pid文件路径
    nodaemon = false ;默认为false在后台运行,改为true即在前台运行
    minfds = 20000 ;系统最少有的空闲文件描述符,低于这个值supervisor不会启动,另外跟最大文件句柄数相关
    minprocs = 200 ;最小可用的进程描述符,低于这个值supervisor将不会正常启动
    ;
    [rpcinterface:supervisor]
    ;supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
    ;给XML_RPC用的,要使用supervisord或者web server必须要开启
    [supervisorctl]
    serverurl = unix:///tmp/supervisor.sock ;supervisorctl本地连接supervisord,使用本地UNIX socke
    ;
    [program:theprogramname] ; 指定管理服务的名称
    command=/bin/tail -f /etc/fstab ; 要执行的进程,可以带参数,不能是守护进程
    ;process_name=%(program_name)s ; numprocs参数为1时,就不用管这个参数 默认值%(program_name)s也就是上面的那个program冒号后面的名字
    ;numprocs=1 ; 启动进程的数目。当不为1时,就是进程池的概念,默认为1
    directory=/tmp ; 进程运行前,会前切换到这个目录
    autostart=true ; 设置为true 子进程将在supervisord启动后被自动启动,默认为true
    startretries=3 ; 进程启动失败后,最大尝试启动的次数 当超过3次后,supervisor将把此进程的状态置为FAIL
    autorestart=unexpected ; 设置子进程挂掉后自动重启的情况,有三个选项,false,unexpected和true。默认为unexpected
    exitcodes=0,2 ; 注意和上面的的autorestart=unexpected对应 exitcodes里面的定义的退出码是expected的。
    stopsignal=QUIT ; 进程停止信号,可以为TERM, HUP, INT, QUIT, KILL, USR1, or USR2等信号 默认为TERM 当用设定的信号去杀掉进程,退出码会被认为是expected
    stopwaitsecs=10 ; 这个是当我们向子进程发送stopsignal信号后,到系统返回信息给supervisord,所等待的最大时间。 超过这个时间,supervisord会向该子进程发送一个强制kill的信号(默认10秒)
    ;stopasgroup=false ; 这个东西主要用于,supervisord管理的子进程,这个子进程本身还有子进程 那么我们如果仅仅干掉supervisord的子进程的话,子进程的子进程有可能会变成孤儿进程 所以咱们可以设置这个选项,把整个该子进程的整个进程组都干掉 设置为true的话,一般killasgroup也会被设置为true 该选项发送的是stop信号(def false)
    ;killasgroup=false ; 这个和上面的stopasgroup类似,不过发送的是kill信号(def false)
    user=chrism ; 如果supervisord是root启动,我们在这里设置这个非root用户,可以用来管理该program 默认不设置
    ;redirect_stderr=true ; 为true,则stderr的日志会被写入stdout日志文件中 (default false)
    stdout_logfile=/a/path ; 子进程的stdout的日志路径,可以指定路径,AUTO,none等三个选项 设置为none的话,将没有日志产生。设置为AUTO的话,将随机找一个地方成日志文件,而且当supervisord重新启动的时候,以前的日志文件会被清空。当 redirect_stderr=true的时候,sterr也会写进这个日志文件
    stdout_logfile_maxbytes=100MB ; 日志文件最大大小,和[supervisord]中定义的一样 (default 50MB)
    ;stdout_logfile_backups=10 ; 和[supervisord]定义的一样 (0 means none, default 10)
    ;stdout_capture_maxbytes=1MB ; 这个东西是设定capture管道的大小,当值不为0的时候,子进程可以从stdout发送信息,而supervisor可以根据信息,发送相应的event (default 0)
    ;stdout_events_enabled=false ; 为ture的时候,当子进程由stdout向文件描述符中写日志的时候,将触发supervisord发送PROCESS_LOG_STDOUT类型的event(default false)
    stderr_logfile=/a/path ; 设置stderr写的日志路径,当redirect_stderr=true。这个就不用设置了,设置了也是白搭。因为它会被写入stdout_logfile的同一个文件中 default AUTO(随便找个地存,supervisord重启被清空)
    stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
    stderr_logfile_backups=10 ; # of stderr logfile backups (default 10)
    ;stderr_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0)
    ;stderr_events_enabled=false ; emit events on stderr writes (default false)
    ;environment=A="1",B="2" ; 这个是该子进程的环境变量,和别的子进程是不共享的
    ;serverurl=AUTO ; override serverurl computation (childutils)
    ;
    ;[group:thegroupname] ; 给programs分组,划分到组里面的program。我们就不用一个一个去操作了 我们可以对组名进行统一的操作。 注意:program被划分到组里面之后,就相当于原来的配置从supervisor的配置文件里消失了supervisor只会对组进行管理,而不再会对组里面的单个program进行管理了
    ;programs=progname1,progname2 ; 组成员,用逗号分开
    ;priority=999 ; 优先级,相对于组和组之间 (default 999)
    [include]
    files = /etc/supervisord/conf.d/*.conf ;包含其他的程序配置文件
  • Tip: 子服务配置/etc/supervisor/conf.d/example1.conf示例(即上面的program配置项可以提取到单独文件)附:我的配置】

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    [program:example1]
    command=/bin/tail -f 121
    directory=/tmp
    user=arvon
    stdout_logfile=/tmp/example1.log
    stdout_logfile_maxbytes=100MB
    stdout_logfile_backups=10
    redirect_stderr=true
    autostart=true
    autorestart=unexpected
    exitcodes=0,2
    stopsignal=QUIT
    stopwaitsecs=20
  • 注意点(踩坑)

    • supervisord中参数minfds和minprocs决定了supervisord进程及其守护的子进程的Max Processes及Max open files,并且这个limit限制不受系统ulimit所影响
    • supervisord守护的子进程无法在supervisord配置文件中单独修改minfds和minprocs这两个参数。下面红色部分的配置是无效的

    以上截取自旺仔牛奶Blog的结论

附:CentOS7与CentOS6对比

CentOS7并没有在生产环境大量使用,刚好可以利用这次线上测试的机会稍微总结下
主要区别大致包含以下几个方面:

  • 基础命令
  • 内核版本(2.x和3.x)
  • 文件系统(ext4和xfs)
  • 安全系统(防火墙)
  • 服务管理(service和systemctl)
  • 新增特性(虚拟化、性能管理、身份管理、网络管理等)

建议

参考文档

【Supervisor官方文档】
【Flowsnow的Blog】
【旺仔牛奶的Blog】