Supervisor 使用和进阶4 (Event 的使用)
本文主要介绍 supervisor Event 的功能。
supervisor 作为一个进程管理工具,在 3.0 版本之后,新增了 Event 的高级特性, 主要用于做(进程启动、退出、失败等)事件告警服务。
Event 特性是将监听的服务(listener)注册到supervisord中,当supervisord监听到相应事件时,将事件信息推送给监听对应事件的listener。
事件类型
Event 可以设置 27 种事件类型,可以分为如下几类:
1. 监控进程状态转移事件;
2. 监控进程状态日志变更事件;
3. 进程组中进程添加删除事件;
4. supervisord 进程本身日志变更事件;
5. supervisord 进程本身状态变更的事件;
6. 定时触发事件。
事件可以被单独监听,也可以一个listener 监听多种事件。
配置说明
对于一个listener,与正常program的区别是,新增了events 参数,用于标识要监听的事件。
[eventlistener:theeventlistenername]
events=PROCESS_STATE,TICK_60
buffer_size=10 ; 事件池子大小(输入流大小)
事件类型配置多个,用逗号分割。上述配置的是子进程状态的变更,以及定时60s通知间隔60s
事件通知缓冲区大小,可以自定义配置,上述配置了10个事件消息的缓冲。
Listener 的实现
与supervisord 的交互
由于supervisord 是 listener的父进程,所以交互方式采用最简单的 标准输入输出的方式交互。listener 通过标准输入获取事件,通过标准输出通知supervisord listener的事件处理结果,以及当前supervisord的状态
listener 的状态
listener 有三种状态:ACKNOWLEDGED、READY、BUSY.
- ACKNOWLEDGED: listener 未就绪的状态。(发送READY之前的状态)
- READY: 等待事件触发的状态。(发送READY 消息后,未收到消息的状态)
- BUSY: 事件处理中的状态。(即输出 OK, FAIL 之前处理Event消息时的状态)
消息协议
消息包括supervisord 通知给listener 的事件消息和 listener 通知给supervisord 的状态变更消息。
listener 的状态变更消息, READY
- 状态OK的 "READY\n" 消息
- 处理成功 "RESULT 2\nOK" 消息
- 处理失败 "RESULT 4\nFAIL" 消息
supervisord 广播的事件消息, 事件消息分为 header 和 payload 两部分。 header 中采用kv的方式发送,header 中包含了 payload 的长度。
例如官网提供的header 的例子:
ver:3.0 server:supervisor serial:21 pool:listener poolserial:10 eventname:PROCESS_COMMUNICATION_STDOUT len:54
header 含义:
- serial 为事件的序列号
- pool 表示listener 的进程池名称(listener支持启动多个)
- poolserial 表示listener的进程池序列号
- eventname 事件名称
- len body 的长度
Listener 的基本流程
listener 的处理流程如下:
1. 发送ready消息,等待事件发生。
2. 收到事件后,处理事件
3. 事件处理完成后,发送 result 消息, 从第一步开始循环
进程状态转移举例
我们以进程状态转移作为例子,做简单介绍。
首先,使用 golang 实现listener
package main
import (
"bufio"
"os"
"strconv"
"strings"
)
const RESP_OK = "RESULT 2\nOK"
const RESP_FAIL = "RESULT 4\nFAIL"
func main() {
stdin := bufio.NewReader(os.Stdin)
stdout := bufio.NewWriter(os.Stdout)
stderr := bufio.NewWriter(os.Stderr)
for {
// 发送后等待接收event
_, _ = stdout.WriteString("READY\n")
_ = stdout.Flush()
// 接收header
line, _, _ := stdin.ReadLine()
stderr.WriteString("read" + string(line))
stderr.Flush()
header, payloadSize := praseHeader(line)
// 接收payload
payload := make([]byte, payloadSize)
stdin.Read(payload)
stderr.WriteString("read : " + string(payload))
stderr.Flush()
result := alarm(header, payload)
if result { // 发送处理结果
stdout.WriteString(RESP_OK)
} else {
stdout.WriteString(RESP_FAIL)
}
stdout.Flush()
}
}
func praseHeader(data []byte) (header map[string]string,
payloadSize int) {
pairs := strings.Split(string(data), " ")
header = make(map[string]string, len(pairs))
for _, pair := range pairs {
token := strings.Split(pair, ":")
header[token[0]] = token[1]
}
payloadSize, _ = strconv.Atoi(header["len"])
return header, payloadSize
}
// 这里设置报警即可
func alarm(header map[string]string, payload []byte) bool {
// send mail
return true
}
这里,报警处理未填写。
其次,在supervisor 中添加配置,监听服务:
[eventlistener:listener]
command=/root/listener
events=PROCESS_STATE,TICK_5
stdout_logfile=/var/log/tmp/listener_test_stdout.log
stderr_logfile=/var/log/tmp/listener_test_stderr.log
user=root
这里监听了服务的处理状态,以及每5s的心跳消息。
最后,启动listener。
supervisorct start listener
从stderr的日志中可以看到,简单的TICK_5 的消息(调整了格式):
header : ver:3.0 server:supervisor serial:256 pool:listener_test poolserial:173 eventname:TICK_5 len:15read
payload: when:1586258030
fastcgi 进程状态变更的消息:
header : ver:3.0 server:supervisor serial:291 pool:listener_test poolserial:208 eventname:PROCESS_STATE_EXITED len:87
payload: processname:fastcgi_test groupname:fastcgi_test from_state:RUNNING expected:0 pid:19119
header :ver:3.0 server:supervisor serial:293 pool:listener_test poolserial:210 eventname:PROCESS_STATE_STARTING len:73
payload: processname:fastcgi_test groupname:fastcgi_test from_state:EXITED tries:0
Supervisor 使用和进阶4 (Event 的使用)的更多相关文章
- 进程管理工具Supervisor(二)Events
supervisor可以当做一个简单的进程启动.重启.控制工具使用,也可以作为一个进程监控框架使用,作为后者,需要使用supervisor的Events机制. Event Listeners supe ...
- 01_Storm体系概要
1. Storm发展历史 Storm历史 1. 2010年12月,backtype公司Nathan,提出Storm的核心概念2. backtype, 提供数据分析,数据处理服务的一个公司3. 2011 ...
- supervisor(二)event
supervisor的event机制其实,就是一个监控/通知的框架.抛开这个机制实现的过程来说的话,event其实就是一串数据,这串数据里面有head和body两部分.咱们先弄清楚event数据结构, ...
- 进阶篇,第二章:MC与Forge的Event系统
<基于1.8 Forge的Minecraft mod制作经验分享> 这一章其实才应该是第一章,矿物生成里面用到了Event的一些内容.如果你对之前矿物生成那一章的将算法插入ORE_GEN_ ...
- SQL Server 扩展事件(Extented Events)从入门到进阶(3)——通过界面操作Extented Event
本文属于 SQL Server扩展事件(Extended Events)从入门到进阶 系列 对于接纳扩展事件,其中一个最大的障碍就是要对XML和XQuery有一定的了解以便分析数据.我们可以使用T-S ...
- Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G
code&monkey Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...
- js进阶课程 12-9 jquery的事件对象event的方法有哪些?
js进阶课程 12-9 jquery的事件对象event的方法有哪些? 一.总结 一句话总结:三组六个,阻止默认事件一组,阻止冒泡一组,阻止冒泡和剩余事件一组. 1.事件的默认动作指什么? 比如点a标 ...
- .NET进阶篇-语言章-2-Delegate委托、Event事件
知识只有经过整理才能形成技能 整个章节分布简介请查看第一篇 内容目录 一.概述 二.解析委托知识点 1.委托本质 2.委托的使用 3.委托意义 逻辑解耦,减少重复代码 代码封装支持扩展 匿名方法和La ...
- Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)
Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...
随机推荐
- Java基础--Java基本数据类型
一.基本数据类型(primitive type) (1)数值型 1.数值型包括整数类型(byte,short,int,long) a.byte :1字节=8bit位 (-128~127) 包装类: ...
- IDEA 配置自定义Apache与PHP环境
1. PHP环境 1.1 插件的安装 1.2 关于php环境的配置 2.关于apache的配置 至此,已经配置成功啦,愉快的学习吧!
- 跨域解决方案之CORS
什么情况表示遇到跨域请求 一般在前后端分离项目中,前端请求接口,浏览器控制台报如下错误 类似 No 'Access-Control-Allow-Origin' header 报错 为什么会有跨域请求 ...
- centOS 6.5 yum升级 gcc4.8 然后又退回来4.4
CentOS 6.5 用了很多年了,一直舍不得省7 . 由于要用到 c++ 11 ,所以决定升级一下. 为了省事我选择用 yum 方式升级,结果最后还是不能用,差点搞坏,这是真机,重装麻烦了. get ...
- 网络|N1盒子做旁路由刷OpenWRT系统(小白专用)
N1盒子做旁路由刷OpenWRT系统(小白专用) 为什么要用N1盒子 现如今新上市的路由器,市面上能买到的300元以内的路由器大多数都是双频(5G Hz和2.4G Hz)和几年前相比无论是速度还是性能 ...
- 【BIM】BIMFACE中创建矢量文本[下篇]
背景 在上一篇文章中,我们通过THREEJS创建了矢量文本,并添加到了BIMFACE场景中,但是仅仅加入到场景中并不是我们的目的,我们的目的是把这种矢量文本加到指定的构件或者空间上,以此标识该构件或空 ...
- vue基础----组件通信($parent,$children)
1.按照dom的父子级关系,在子组件中可以通过$parent 直接调用父组件的方法,也可得到父组件的属性. 2.在父组件中通过$childrens可以得到一个子组件数组,能够在父组件中调用子组件的方法 ...
- vquery 一些应用
// JavaScript Document function myAddEvent(obj,sEv,fn){ if(obj.attachEvent){ obj.attachEvent('on'+sE ...
- beforeEach 之 next
在这里我用通俗点的说法解释上next(),next(false),next('/'),next(error),希望通过这接地气的解释你能掌握这几个知识点.背景:你乘坐汽车从A景区想赶往B景区(模拟路由 ...
- Linux中MySQL二进制安装步骤
MySQL二进制安装步骤 安装依赖环境 [root@node3 ~]# yum -y install libaio 将mysql-5.7.26-linux-glibc2.12-x86_64.tar.g ...