supervisord 搭建与积累

这篇文章主要是自己对supervisord学习的一个总结。可能总结有不对的地方,希望大家留言指正。

supervisord主要是用于管理服务进程。可以把那些运行在后台的服务放在supervisor中进行管理,监控和报警。

安装supervisor

# 安装pip,可以用源码安装(推荐),也可以用镜像源安装。
yum install -y python-pip

# 安装supervisord
pip install supervisord

# 生成supervisord配置文件
echo_supervisord_conf >> /etc/supervisord.conf

# 启动supervisord服务
supervisord -c /etc/supervisord.conf

# 设定扩展目录
echo "files = /etc/supervisord.conf.d/*.conf" >> /etc/supervisord.conf

配置supervisord服务配置demo

;[program:theprogramname]                                                                                                                                                                  
;command=/bin/cat              ; # 运行的程序命令                                                                                                    
;process_name=%(program_name)s ; # 程序进程                                                                                                     
;numprocs=1                    ; # 启动线程,默认1.有些自动以服务支持多个线程。                                                                              
;directory=/tmp                ; # 执行前切换的工作目录                                                                                 
;umask=022                     ; # umask for process (default None)                                                                                                                          
;priority=999                  ; # the relative start priority (default 999)                                                                                                                 
;autostart=true                ; # supervisord启动时候自启动                                                                                                  
;startsecs=1                   ; # 启动时候延迟秒数                                                                                              
;startretries=3                ; # 失败时尝试重启次数                                                                                           
;autorestart=true              ; # 自动重启                                                                                                 
;exitcodes=0,2                 ; # 捕捉退出信号ID后重启                                                                                               
;stopsignal=QUIT               ; # 停止方式                                                                                            
;stopwaitsecs=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=true          ; # 重定向stderr                                                                                           
;stdout_logfile=/a/path        ; # stdout重定向日志                                                                                           
;stdout_logfile_maxbytes=1MB   ; # 设定单个日志文件大小。满容后自动切换备份                                                                                       
;stdout_logfile_backups=10     ; #                                                                                       
;stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)                                                                                                              
;stdout_events_enabled=false   ; emit events on stdout writes (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 (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"       ; process environment additions (def no adds)                                                                                                               
;serverurl=AUTO                ; override serverurl computation (childutils)    

supervisord停止/重启服务问题整理

1,在配置文件指定stopsignal方式。常见默认有 QUIT,TERM,INT。supervisorctl模拟kill命令结束服务,kill -l命令可以查看kill的方式,kill -l INT 查看退出时发出的信号ID,exitcodes会捕捉这些结束ID判断是否重启

2,在supervisor停止时候,只会对当前的命令或脚本发出结束信号。如果脚本A或命令A新运行了进程B。那么A的父ID是supervisor,B的父ID是A。supervisord只能停止A,B需要由A发出信号停止。反之B因为A结束而找不到父ID,B的父ID则变更为1(root)

supervisor监控的报警

在配置文件中可以找到[eventlistener:x]部分实现事件侦听器。

eventlistener监听program的stdin数据流信息获取program的相关程序状态
eventlistener监听eventlistener的stdin数据流信息来确定自己当前监听状态。监听状态:ACKNOWLEDGED,READY,BUSY。

supervisord整理program的输出。

Created with Raphaël 2.1.2 supervisor捕捉并整理program日志 supervisor程序整理日志 确定stdout/stderr日志 无误的日志 错误的日志 yes no

supervisord监控program的输出状态。

Created with Raphaël 2.1.2 告诉supervisord输出ready捕捉数据 获得supervisor整理日志 日志分析并发送监控信息 告诉supervisord输出ok确定进入下一循环

supervisor的eventlistener配置。整体与program是一样

[eventlistener:listenername]  ;  # 监控事件别名
command=/bin/eventlistener    ;  # 运行的命令
process_name=%(program_name)s ;  # 运行的program名
directory=/                   ;  # 运行的脚本路径
events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING,PROCESS_STATE_FATAL  ; # 需要监控的状态,具体在supervisord查找

简单的日志整理报警脚本

#!/usr/bin/env python

# 监控的状态
EVENT_STATE = {
    'PROCESS_STATE_EXITED' : 'EXITED',
    'PROCESS_STATE_RUNNING': 'RUNNING',
    'PROCESS_STATE_FATAL'  : 'FATAL'
}
# stdout输出
def write_stdout(s):
    sys.stdout.write(s)
    sys.stdout.flush()
# stdin输出
def write_stderr(s):
    sys.stderr.write(s+"\n")
    sys.stderr.flush()

def main():
    # 判断是否由supervisor运行
    if not 'SUPERVISOR_SERVER_URL' in os.environ:
        print "%s must be run as a supervisor listener." % sys.argv[0]
        return

    # 死循环监控。
    while True:
        # 告诉supervisor进入ready状态。
        write_stdout('READY\n')

        # 获取supervisor捕捉并整理的数据
        line = sys.stdin.readline()

        # 获取当前信息的基本信息。
        eventname:PROCESS_STATE_RUNNING len:67
        headers = dict([ x.split(':') for x in line.split() ]) # ex: ver:3.0 server:supervisor serial:2951 pool:listener poolserial:261  

        # 获取准确完整的数据,从headers得到长度并切割
        process_data = sys.stdin.read(int(headers['len'])) # processname:mysql groupname:mysql from_state:RUNNING expected:0 pid:29110
        process_info = dict([ x.split(':') for x in process_data.split()]) 

        # 这里可以输出到event监听事件的日志里。使用stderr输出到日志
        write_stderr(str(process_info))

        # 整理数据
        send_data = [
            "服务器%s进程" %(HOSTNAME),
            "运行服务:%s,pid:%d" %(process_info['processname'], int(process_info.get('pid',0))),
            "上次状态:%s" %(process_info['from_state']),
            "当前状态:%s" %(EVENT_STATE[headers['eventname']]),
            "发生时间:%s" %(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
        ]

        # 讲数据发出去
        rs = send_msg("\n".join(send_data).encode('utf-8'))
        # 发出结果记录到eventlisten日志进行查看
        write_stderr(rs)

        # 告诉supervisor已经整理完。并进入下一个循环
        write_stdout('RESULT 2\nOK')

if __name__ == '__main__':
    main()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值