docker事件events监控实现分析
go event
实现原理
- 使用一个队列保存events事件,先进入到队列的事件先得到处理
- 开启一个协程,循环检测队列中是否有事件
- 队列事件的写入必须在另外的协程中,所以必须使用锁保护队列events数据
- 设计 sink 装载events,为保证设计的兼容性,sink设计为interface,sink可理解为:运输船,将event事件运输到相应的协程
- sink 配合channel可以实现多协程间事件通知
- golang channel 为一对一方式通知,设计broadcast广播通知所有相关sinks
代码分析
核心代码文件:
go-events/event.go
go-events/queue.go
// Event marks items that can be sent as events.
type Event interface{} //事件:声明为interface{}可兼容所有数据类型// 槽的兼容性考虑
type Sink interface {// Write an event to the Sink. If no error is returned, the caller will// assume that all events have been committed to the sink. If an error is// received, the caller may retry sending the event.Write(event Event) error// Close the sink, possibly waiting for pending events to flush.Close() error
}
Event 为事件原型, 实现了Sink的方法都可以作为sink
Queue类型声明
type Queue struct {dst Sink //处理事件或转载事件的槽events *list.List //转载事件,cond *sync.Cond //mu sync.Mutex //List的数据涉及到多协程改动,使用“锁”保护数据完整性closed bool
}
新建事件监控时,会启动一个协程循环检测List(实现为队列)中的事件
func (eq *Queue) run() {for {event := eq.next() //获取LIST中的事件,若LIST没有事件将阻塞if event == nil {return // nil block means event queue is closed.}if err := eq.dst.Write(event); err != nil { //调用sink的write方法,处理eventlogrus.WithFields(logrus.Fields{"event": event,"sink": eq.dst,}).WithError(err).Debug("eventqueue: dropped event")}}
}
Quene 的write方法,由其他协程调用,向List中写入event数据;
最后达到的效果:有一个协程从始至终检测events事件,当另外的协程调用Queue的write方法写入事件时,检测到有event事件来,使用sink(具体上次实现)write方法处理事件;
docker watch机制
docker 实现了watch机制,等待事件获取数据
watch使用
//监控queue事件队列上的EventUpdataTask事件
Watch(queue, EventUpdateTask{})
Watch函数源码(state/watch.go)
func Watch(queue *watch.Queue, specifiers ...Event) (eventq chan events.Event, cancel func()) {if len(specifiers) == 0 {return queue.Watch() // queue 默认watch函数}return queue.CallbackWatch(events.MatcherFunc(func(event events.Event) bool {for _, s := range specifiers {if s.matches(event) {return true}}return false}))
}
向CallbackWatch传入了一个匿名事件匹配函数
CallbackWatch函数(state/watch/watch.go)
func (q *Queue) CallbackWatch(matcher events.Matcher) (eventq chan events.Event, cancel func()) {ch := events.NewChannel(0) //event使用channel 封装,为了通知其他协程sink := events.Sink(events.NewQueue(ch))// 封装为sinkif matcher != nil {sink = events.NewFilter(sink, matcher) //使用Filter实现的sink:实现filter方法,检测事件筛选}q.broadcast.Add(sink) //将sink添加到 broadcastreturn ch.C, func() {q.broadcast.Remove(sink)ch.Close()sink.Close()}
}
events.NewChannel
events.NewFilter
events.Broadcast
都是sink的实现特殊功能的封装类,具体实现参考源码:go-events目录下 filter.go broadcast.go channel.go
events.Broadcast
特殊说明下:golang 的channel相当于一个管道,只能实现协程间一对一的通信;为了实现一对多的情况,go-events实现了broadcast机制:list中有事件后,通知broadcast,再由broadcast遍历其中所有的sink,调用sink的write处理方法,通知相应的协程(一般情况是channel信号,协程根据channel执行相应events动作)
通知Watch向注册监控事件,并获取返回的channel,并在当前协程阻塞、监控channel,当事件发生时,当前协程可通过channel获取事件类型作出相应的动作。
docker事件events监控实现分析相关推荐
- 特定热点事件监控与分析项目
EventMonitor Event monitor based on online news corpus built by Baidu search enginee using event key ...
- 电量优化中-电量监控和分析工具
电量监控和分析工具 Android 5.0开始 提供了电量获取和分析的方式 一.使用adb 命令 dumpsys batteryst 生成电池的使用情况 二.使用Battery Historian 分 ...
- 灵雀云首席架构师:Docker容器的监控技术
前言 在Docker容器技术飞速发展之时,监控容器的效率与健康也变成了至关重要的需求.在Docker资深提供的监控技术逐渐成熟时,来自第三方的监控工具也同时步入了人们的视线. 本文将为大家介绍Dock ...
- 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 七 )
Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...
- 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 六 )
Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...
- 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 五 )
Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...
- 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 四 | View 事件传递机制 )
Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...
- 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 三 )
Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...
- 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 二 )
Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...
最新文章
- Win7系统分区(C盘)扩容的一种可行的解决方案
- Python学习第三天--数据类型
- shiro教程(2)- shiro介绍
- 查找满足断言的第一个元素
- BZOJ4517: [Sdoi2016]排列计数
- 盛大“传奇”的网游启示录
- c语言打印字符数据在屏幕上,在屏幕上输出各种类型的数据
- 离线语音控制系统 唤醒词.命令字
- 倾向得分匹配PSM案例分析
- 【POJ No. 3294】星际迷航 Life Forms
- Plotting data
- python海龟图画龙珠_DeepOps的Python小笔记-天池龙珠计划-Python训练营-Task 02:DAY4
- burp安装及代理设置
- ios 微信越狱使用指纹支付插件
- 腾讯优图提出LAP无监督多视角人脸3D重建算法,高清还原面部细节
- HighSpeedCharting简单的使用
- 软件开发中的需求分析
- 华云大咖说 | 安超虚拟化平台全“芯”亮点揭秘
- 细说振动位移、速度、加速度
- C语言之求两个整数之和