[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的语言特性,你根部不必进行任何操作就可以进行属性的 ...
随机推荐
- js清除浏览器的缓存的方法
许多的项目当中,一旦改动了js的代码,必须在浏览器当中重新加载数据,清理缓存,比较麻烦.网上找了很多的清除浏览器的方法,首先是在 html的头部加上meta的属性,但是发现并没有什么用处,后来看到说在 ...
- Pycharm中设置默认头注释
在编写Python项目时,我们可能需要添加一些默认的信息,比如添加文件创建的时间,比如添加文件作者,等等,这些信息可以自己在python脚本中添加,但是也可以在Pycharm中配置模板,每次创建文件的 ...
- 牛客NOIP暑期七天营-提高组2C:滑块(平衡树) (这里rope骗分)
A:hash 或者 map 或者trie. #include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) usin ...
- IDEA 注释模板
类.接口.等文件注释: /** * @Description: * @author: tangsw * @date: ${DATE} ${TIME} * */ 方法上注释: /** * @Descri ...
- MySQL - binlog日志简介及设置
基本概念 binlog是Mysql sever层维护的一种二进制日志,与innodb引擎中的redo/undo log是完全不同的日志:其主要是用来记录对mysql数据更新或潜在发生更新的SQL语句, ...
- Game Based Learning: Why Does it Work?
Forty years of research[i] says yes, games are effective learning tools. People learn from games, an ...
- [HTTP趣谈]origin,referer和host区别
发起一个ajax请求时,request header里面有三个属性会涉及请求源信息.前端可能用不到这些值,但是,后台业务系统会比较关心它们,场景可能有: 处理跨域请求时,必须判断来源请求方是否合法: ...
- bzoj4066: 简单题 K-Dtree
bzoj4066: 简单题 链接 bzoj 思路 强制在线.k-dtree. 卡常啊.空间开1e6就T了. 代码 #include <bits/stdc++.h> #define my_m ...
- 2019 SDN上机第七次作业
1.补充并运行basic /* -*- P4_16 -*- */ #include <core.p4> #include <v1model.p4> const bit<1 ...
- GoCN每日新闻(2019-11-06)
GoCN每日新闻(2019-11-06) GoCN每日新闻(2019-11-06) 1. 使用构建标签分离你的测试文件 https://mickey.dev/posts/go-build-tags-t ...