[Golang] ETCD键值监听器
0x0 需求
我们所有的服务启动后都以lease形式注册入ETCD,现要把这些服务监控起来。
0x1 ETCD key监听器实现
可动态增删要监听的键值对
https://github.com/bailu1901/pkg/blob/master/etcd_watcher/watcher.go
// Package etcd_watcher ETCD键值监听器
package etcd_watcher import (
"context"
"sync"
"time" "github.com/coreos/etcd/clientv3"
"github.com/coreos/etcd/mvcc/mvccpb"
) var (
timeOut = time.Duration() * time.Second // 超时
) // Listener 对外通知
type Listener interface {
Set([]byte, []byte)
Create([]byte, []byte)
Modify([]byte, []byte)
Delete([]byte)
} // EtcdWatcher ETCD key监视器
type EtcdWatcher struct {
cli *clientv3.Client // etcd client
wg sync.WaitGroup
listener Listener
mu sync.Mutex
closeHandler map[string]func()
} // NewEtcdWatcher 构造
func NewEtcdWatcher(servers []string) (*EtcdWatcher, error) {
cli, err := clientv3.New(clientv3.Config{
Endpoints: servers,
DialTimeout: timeOut,
})
if err != nil {
return nil, err
} ew := &EtcdWatcher{
cli: cli,
closeHandler: make(map[string]func()),
} return ew, nil
} // AddWatch 添加监视
func (mgr *EtcdWatcher) AddWatch(key string, prefix bool, listener Listener) bool {
mgr.mu.Lock()
defer mgr.mu.Unlock()
if _, ok := mgr.closeHandler[key]; ok {
return false
}
ctx, cancel := context.WithCancel(context.Background())
mgr.closeHandler[key] = cancel mgr.wg.Add()
go mgr.watch(ctx, key, prefix, listener) return true
} // RemoveWatch 删除监视
func (mgr *EtcdWatcher) RemoveWatch(key string) bool {
mgr.mu.Lock()
defer mgr.mu.Unlock()
cancel, ok := mgr.closeHandler[key]
if !ok {
return false
}
cancel()
delete(mgr.closeHandler, key) return true
} // ClearWatch 清除所有监视
func (mgr *EtcdWatcher) ClearWatch() {
mgr.mu.Lock()
defer mgr.mu.Unlock()
for k := range mgr.closeHandler {
mgr.closeHandler[k]()
}
mgr.closeHandler = make(map[string]func())
} // Close 关闭
func (mgr *EtcdWatcher) Close(wait bool) {
mgr.ClearWatch() if wait {
mgr.wg.Wait()
} mgr.cli.Close()
mgr.cli = nil
} func (mgr *EtcdWatcher) watch(ctx context.Context, key string, prefix bool, listener Listener) error {
defer mgr.wg.Done() ctx1, cancel := context.WithTimeout(context.Background(), timeOut)
defer cancel()
var getResp *clientv3.GetResponse
var err error
if prefix {
getResp, err = mgr.cli.Get(ctx1, key, clientv3.WithPrefix())
} else {
getResp, err = mgr.cli.Get(ctx1, key)
}
if err != nil {
return err
} for _, ev := range getResp.Kvs {
listener.Set(ev.Key, ev.Value)
} var watchChan clientv3.WatchChan
if prefix {
watchChan = mgr.cli.Watch(context.Background(), key, clientv3.WithPrefix(), clientv3.WithRev(getResp.Header.Revision+))
} else {
watchChan = mgr.cli.Watch(context.Background(), key, clientv3.WithRev(getResp.Header.Revision+))
}
for {
select {
case <-ctx.Done():
return nil
case resp := <-watchChan:
err := resp.Err()
if err != nil {
return err
}
for _, ev := range resp.Events {
if ev.IsCreate() {
listener.Create(ev.Kv.Key, ev.Kv.Value)
} else if ev.IsModify() {
listener.Modify(ev.Kv.Key, ev.Kv.Value)
} else if ev.Type == mvccpb.DELETE {
listener.Delete(ev.Kv.Key)
} else {
}
}
}
}
}
0x3 配合发送邮件做报警
https://github.com/bailu1901/pkg/tree/master/mailbox
[Golang] ETCD键值监听器的更多相关文章
- etcd:用于服务发现的键值存储系统
etcd是一个高可用的键值存储系统,主要用于共享配置和服务发现.etcd是由CoreOS开发并维护的,灵感来自于 ZooKeeper 和 Doozer,它使用Go语言编写,并通过Raft一致性算法处理 ...
- 分布式键值存储系统ETCD调研
分布式键值存储系统ETCD调研 简介 etcd是一个开源的分布式键值存储工具--为CoreOS集群提供配置服务.发现服务和协同调度.Etcd运行在集群的每个coreos节点上,可以保证coreos集群 ...
- docker——Etcd高可用键值对数据库
一.简介 Etcd按照官方介绍: Etcd is a distributed, consistent key-value store for shared configuration and serv ...
- 探索etcd,Zookeeper和Consul一致键值数据存储的性能
这篇博文是探索三个分布式.一致性键值数据存储软件性能的系列文章中的第一篇:etcd.Zookeeper和Consul,由etcd团队所写,可以让我们全面地了解如何评估三个分布式一致存储软件的性能.翻译 ...
- PowerDotNet平台化软件架构设计与实现系列(05):ETCD分布式键值存储平台
ETCD目前在PowerDotNet已经被用于注册中心和配置管理(常见的配置中心在PowerDotNet中仅仅是一个小小的模块而已)中,作为基础设施的重要组成部分,ETCD的重要性不言而喻. 本文简单 ...
- KVO 键值观察者
KVO(键值观察者) //监听的创建 -(id)initChildren:(Person *)person { self = [super init]; if (self != nil) { //拥有 ...
- ios中键值编码kvc和键值监听kvo的特性及详解
总结: kvc键值编码 1.就是在oc中可以对属性进行动态读写(以往都是自己赋值属性) 2. 如果方法属性的关键字和需要数据中的关键字相同的话 ...
- xcode KVC:Key Value Coding 键值编码
赋值 // 能修改私有成员变量 - (void)setValue:(id)value forKey:(NSString *)key; - (void)setValue:(id)value forKey ...
- iOS监听模式系列之键值编码KVC、键值监听KVO的简单介绍和应用
键值编码KVC 我们知道在C#中可以通过反射读写一个对象的属性,有时候这种方式特别方便,因为你可以利用字符串的方式去动态控制一个对象.其实由于ObjC的语言特性,你根部不必进行任何操作就可以进行属性的 ...
随机推荐
- seaborn---调色板
一.样式控制 1.set([context,style,palette,font,...]) 一步设定美学参数. 2.axes_style([style,rc]) 返回参数字典,用于绘图的美学风格. ...
- 开发基础之牛逼哄哄的 Lambda 表达式,简洁优雅就是生产力
什么是Lambda? 我们知道,对于一个Java变量,我们可以赋给其一个“值”. 如果你想把“一块代码”赋给一个Java变量,应该怎么做呢? 比如,我想把右边那块代码,赋给一个叫做aBlockOfCo ...
- 错误 Unable to connect to a repository at URL 'svn://ip地址' 和 No repository found in 'svn://ip地址'
SVN服务器是CentOS6.10 使用TortoiseSVN客户端检出时遇到如下图所示的错误: 是因为没有指定SVN仓库的路径 在SVN服务器执行命令:svnserve -d -r /SVN版本库的 ...
- Java中对象的比较(学习笔记)
1)详细说明对象的比较方式有哪些? ①对象引用的比较("= ="运算符) "= ="是将对象的引用进行比较,实质是比较两个引用变量是否引用同一个对象.注意的点: ...
- hdu4027-Can you answer these queries? -(线段树+剪枝)
题意:给n个数,m个操作,分两种操作,一种是将一段区间的每个数都开根号,另一种是查询区间和. 解题:显然对每个数开根号不能用lazy的区间更新.一个一个更新必然爆时间,对1开根号还是1,如果一段区间都 ...
- 基于Docker方式实现Elasticsearch集群
采用docker容器,搭建两个es集群,可根据步骤自行扩展n+集群 1.创建es挂载目录 cd /usr/localmkdir -p es/config 2.创建es存放数据目录 cd esmkdir ...
- vue基于iview树状表格,封装完善
先安装iview后在使用 完善按钮不显示问题 ,当children过多时,点击不动问题等 封装 <template> <div :style="{width:tableWi ...
- Hibernate的事务
1.数据库的封锁(https://www.cnblogs.com/zhai1997/p/11710082.html): 封锁是实现并发控制的重要技术. read uncommitted : 读取尚未提 ...
- ava js 测试框架基本试用
随着js 越来越强大,日常使用中关于js 的问题也就越突出了,我们需要关注的点也就不能只像以前那样 只编写简单的功能实现,我们同时也需要关注js 的健壮性,测试就是其中一个比较重要的环节,以下 是av ...
- C# VS常用操作
VS点击项目,就会打开文件,其实我只是想选中而已, 在这个地方可以改. 原文:https://blog.csdn.net/yellowegg/article/details/12217309