为了确保线上项目的稳定性,须要对supervisor屡次从新拉启失败后的进程,进行钉钉告警,以便相关的技术人员能及时处理。
具体实现的效果以下:php
这里针对从没有接触过supervisor和钉钉机器人对读者的一个扫盲,若是你已经很熟悉了,能够直接跳过。
一、什么是supervisor?
supervisor是python编写的一个可靠的进程管理工具,它会对其管理的子进程进行监控,当进程出现意外crash的时候,它将会尝试从新拉起继续执行(能够设置最多拉起次数,通常也不会无限去拉起失败的进程)。咱们只须要知道它的大概做用便可,具体能够参考supervisor官网html
二、什么是钉钉机器人?
钉钉机器人,是基于钉钉软件的,对钉钉群功能对一种扩展。群机器人能够将第三方服务的信息聚合到群聊中,实现自动化的信息同步。机器人的种类有不少如gitlab机器人、github机器人、cooding机器人等,这里咱们使用的是自定义机器人,具体能够参考官网介绍python
一、打开钉钉软件,找到机器人管理git
二、单击机器人管理,出现机器人管理菜单,大概是这个样子github
剩下的步骤在官网上已经有了很详细的说明,我就再也不赘述了戳这里shell
到最后咱们会获得一个带有access_token的url连接,咱们就是经过对这个url发起post请求进行告警,它大概是下面这个样子:json
https://oapi.dingtalk.com/robot/send?access_token=XXXXXX
(ps:本文采用了ip限制的策略)c#
首先,先看下supervisor eventlistner的配置文件内容:api
[eventlistener:monitor] command=/home/zero/supervisord.d/monitor.py events=PROCESS_STATE_FATAL stdout_logfile=/var/log/supervisor/script_log/monitor.log stderr_logfile=/var/log/supervisor/script_log/monitor@error.log
简单的分析一下上面的配置
第一行:[eventlistener:monitor],接触过supervisor的同窗都知道,通常状况下supervisor的子进程的配置第一行通常都是[program:进程名称], 而这里是 [eventlistener:监听者名称] 的形式,代表这个是一个关于事件监听者的配置,监听者的进程名称叫作monitor。
第二行:command=/home/zero/supervisord.d/monitor.py ,表明执行该进程的命令,下面会详细介绍一下,这里暂时忽略。
第三行:events=PROCESS_STATE_FATAL,表明监听者监听的事件。截止supervisor 4.1 这个版本,目前支持23个事件,它们分别是:markdown
PROCESS_STATE PROCESS_STATE_STARTING PROCESS_STATE_RUNNING PROCESS_STATE_BACKOFF PROCESS_STATE_STOPPING PROCESS_STATE_EXITED PROCESS_STATE_STOPPED PROCESS_STATE_FATAL PROCESS_STATE_UNKNOWN REMOTE_COMMUNICATION PROCESS_LOG_STDOUT PROCESS_LOG_STDERR PROCESS_COMMUNICATION_STDOUT PROCESS_COMMUNICATION_STDERR SUPERVISOR_STATE_CHANGE SUPERVISOR_STATE_CHANGE_RUNNING SUPERVISOR_STATE_CHANGE_STOPPING TICK_5 TICK_60 TICK_3600 PROCESS_GROUP PROCESS_GROUP_ADDED PROCESS_GROUP_REMOVED
详细的介绍能够查看这里
这里咱们关注的是 PROCESS_STATE_FATAL 事件,这个事件是什么意思呢?下面是官网的洋文:
Indicates a process has moved from the BACKOFF state to the FATAL state. This means that Supervisor tried startretries number of times unsuccessfully to start the process, and gave up attempting to restart it. 当这个事件发生的时候,意味着supervisor的子进程从BACKOFF 变为了 FATAL状态。 意味着supervisor屡次(重起次数,看本身的配置)尝试重启子进程,依然失败,决定放弃
第四行、第五行:表明着监听者在监听过程当中 标准输出日志、错误日志的输出位置
这里咱们承接上面提到的command配置项,command配置的是eventlistener的真正监听的真正执行者,也就是上文提到的/home/zero/supervisord.d/monitor.py 脚本。理论上监听脚本能够用任何语言编写,可是因为supervisor自己是用python编写的,而且提供了一个名字叫作supervisor.childutils 的模块。这样一来使用python脚本去编写监听者将会异常的简单。官网上提供了一个简单的👇demo👇,而咱们须要作的就是针对demo进行一个二次的开发,代码以下:
#!/usr/bin/env python import sys import urllib2 import json def write_stdout(s): # only eventlistener protocol messages may be sent to stdout sys.stdout.write(s) sys.stdout.flush() def write_stderr(s): sys.stderr.write(s) sys.stderr.flush() def main(): while 1: # transition from ACKNOWLEDGED to READY write_stdout('READY\n') # read header line and print it to stderr line = sys.stdin.readline() # read event payload and print it to stderr headers = dict([ x.split(':') for x in line.split() ]) notifyData = sys.stdin.read(int(headers['len'])) title = "warning online" content = "### supervisor sub process failed\n" + "> \n" + "> " + notifyData +"\n" url = "设置自定义机器人时获得的连接" headers = {'Content-Type':'application/json'} body = {'msgtype':'markdown', 'markdown':{'title':title, 'text':content, 'at':{'isAtAll':'true'}}} request = urllib2.Request(url,headers=headers,data=json.dumps(body)) response = urllib2.urlopen(request) # transition from READY to ACKNOWLEDGED write_stdout('RESULT 2\nOK') if __name__ == '__main__': main()
(ps:这里使用的是支持markdown 格式的告警内容)
好了,配置完毕,enjoy!!!因为我的能力有限,若有纰漏,不吝赐教!
supervisor官网 http://www.supervisord.org/index.html
钉钉文档机器人的官网文档 https://ding-doc.dingtalk.com/doc#/serverapi2/krgddi