本文主要介绍 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

events 参考

Supervisor 使用和进阶4 (Event 的使用)的更多相关文章

  1. 进程管理工具Supervisor(二)Events

    supervisor可以当做一个简单的进程启动.重启.控制工具使用,也可以作为一个进程监控框架使用,作为后者,需要使用supervisor的Events机制. Event Listeners supe ...

  2. 01_Storm体系概要

    1. Storm发展历史 Storm历史 1. 2010年12月,backtype公司Nathan,提出Storm的核心概念2. backtype, 提供数据分析,数据处理服务的一个公司3. 2011 ...

  3. supervisor(二)event

    supervisor的event机制其实,就是一个监控/通知的框架.抛开这个机制实现的过程来说的话,event其实就是一串数据,这串数据里面有head和body两部分.咱们先弄清楚event数据结构, ...

  4. 进阶篇,第二章:MC与Forge的Event系统

    <基于1.8 Forge的Minecraft mod制作经验分享> 这一章其实才应该是第一章,矿物生成里面用到了Event的一些内容.如果你对之前矿物生成那一章的将算法插入ORE_GEN_ ...

  5. SQL Server 扩展事件(Extented Events)从入门到进阶(3)——通过界面操作Extented Event

    本文属于 SQL Server扩展事件(Extended Events)从入门到进阶 系列 对于接纳扩展事件,其中一个最大的障碍就是要对XML和XQuery有一定的了解以便分析数据.我们可以使用T-S ...

  6. Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G

    code&monkey   Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...

  7. js进阶课程 12-9 jquery的事件对象event的方法有哪些?

    js进阶课程 12-9 jquery的事件对象event的方法有哪些? 一.总结 一句话总结:三组六个,阻止默认事件一组,阻止冒泡一组,阻止冒泡和剩余事件一组. 1.事件的默认动作指什么? 比如点a标 ...

  8. .NET进阶篇-语言章-2-Delegate委托、Event事件

    知识只有经过整理才能形成技能 整个章节分布简介请查看第一篇 内容目录 一.概述 二.解析委托知识点 1.委托本质 2.委托的使用 3.委托意义 逻辑解耦,减少重复代码 代码封装支持扩展 匿名方法和La ...

  9. Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)

    Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...

随机推荐

  1. spring boot 整合elasticsearch

    1.导入jar包 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncodi ...

  2. Ajax同步和异步的区别?

    今天在code review时候看到同事的代码,用了ajax同步,async:false,如果不设置async参数,默认是true,为异步,异步的情况是比较复杂的,看下同步这个例子: function ...

  3. Java基础面试系列(一)

    Java基础面试总结(一) 1. 面向对象和面向过程的区别 面向过程 面向对象 性能 高于面向对象 类加载的时候需要实例化,比较消耗资源 三易(易维护,易复用,易扩展) 不如面向对象 具有封装,继承, ...

  4. SpringBoot框架——从SpringBoot看IoC容器初始化流程之方法分析

    目录 一.概观Spring Boot 二.Spring Boot应用初始化 2.1 初始化入口 2.2 SpringApplication的run方法 2.3 方法分析 三.容器创建与初始化 3.1 ...

  5. flask 分页数据显示

    填充一些数据在表中 @blue.route('/pages/') def pages(): # 默认进入这个视图函数 第一页并只显示5条数据 page = request.args.get('page ...

  6. JAVAEE学习day05学习,数组

    容器及元素的概念 容器:是将多个数据存储到一起 元素:每个数据称为该容器的元素 数组的概念 数组:数组是长度固定,存储数据的容器,保证多个数据的类型要一致 数组定义格式及其描述 动态定义: 数据类型 ...

  7. 【分布式锁】01-使用Redisson实现可重入分布式锁原理

    前言 主流的分布式锁一般有三种实现方式: 数据库乐观锁 基于Redis的分布式锁 基于ZooKeeper的分布式锁 之前我在博客上写过关于mysql和redis实现分布式锁的具体方案:https:// ...

  8. 面试话痨(二)C:JAVA String,别以为你穿个马甲我就不认识你了

    面试话痨系列是从技术广度的角度去回答面试官提的问题,适合萌新观看!   面试官,别再问我火箭怎么造了,我知道螺丝的四种拧法,你想听吗? String相关的题目,是面试中经常考察的点,当面试中遇到了St ...

  9. win7 win10 更换电脑盘符的图标

    效果如下 第一步 -> 1.把文件全放到盘符住目录 2.如果需要更换图标 (文件最好是ICO后缀的) 打开 Autorun 文件并编辑 第二步 -> 重启电脑就完了 下载连接  已经放到码 ...

  10. Linux vi编辑的常用的操作备忘

    1 复制 1) 单行复制 在命令模式下,将光标移动到将要复制的行处,按"yy"进行复制: 2) 多行复制 在命令模式下,将光标移动到将要复制的首行处,按"nyy" ...