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键值监听器的更多相关文章

  1. etcd:用于服务发现的键值存储系统

    etcd是一个高可用的键值存储系统,主要用于共享配置和服务发现.etcd是由CoreOS开发并维护的,灵感来自于 ZooKeeper 和 Doozer,它使用Go语言编写,并通过Raft一致性算法处理 ...

  2. 分布式键值存储系统ETCD调研

    分布式键值存储系统ETCD调研 简介 etcd是一个开源的分布式键值存储工具--为CoreOS集群提供配置服务.发现服务和协同调度.Etcd运行在集群的每个coreos节点上,可以保证coreos集群 ...

  3. docker——Etcd高可用键值对数据库

    一.简介 Etcd按照官方介绍: Etcd is a distributed, consistent key-value store for shared configuration and serv ...

  4. 探索etcd,Zookeeper和Consul一致键值数据存储的性能

    这篇博文是探索三个分布式.一致性键值数据存储软件性能的系列文章中的第一篇:etcd.Zookeeper和Consul,由etcd团队所写,可以让我们全面地了解如何评估三个分布式一致存储软件的性能.翻译 ...

  5. PowerDotNet平台化软件架构设计与实现系列(05):ETCD分布式键值存储平台

    ETCD目前在PowerDotNet已经被用于注册中心和配置管理(常见的配置中心在PowerDotNet中仅仅是一个小小的模块而已)中,作为基础设施的重要组成部分,ETCD的重要性不言而喻. 本文简单 ...

  6. KVO 键值观察者

    KVO(键值观察者) //监听的创建 -(id)initChildren:(Person *)person { self = [super init]; if (self != nil) { //拥有 ...

  7. ios中键值编码kvc和键值监听kvo的特性及详解

    总结: kvc键值编码  1.就是在oc中可以对属性进行动态读写(以往都是自己赋值属性)           2. 如果方法属性的关键字和需要数据中的关键字相同的话                  ...

  8. xcode KVC:Key Value Coding 键值编码

    赋值 // 能修改私有成员变量 - (void)setValue:(id)value forKey:(NSString *)key; - (void)setValue:(id)value forKey ...

  9. iOS监听模式系列之键值编码KVC、键值监听KVO的简单介绍和应用

    键值编码KVC 我们知道在C#中可以通过反射读写一个对象的属性,有时候这种方式特别方便,因为你可以利用字符串的方式去动态控制一个对象.其实由于ObjC的语言特性,你根部不必进行任何操作就可以进行属性的 ...

随机推荐

  1. 1062 Error 'Duplicate entry '1438019' for key 'PRIMARY'' on query

    mysql主从库同步错误:1062 Error 'Duplicate entry '1438019' for key 'PRIMARY'' on querymysql主从库在同步时会发生1062 La ...

  2. SpringBoot——经典的Hello World【二】

    前言 来创建个hello world 呗 步骤 首先肯定是要打开我们的IDEA来创建一个Maven的项目哈 创建项目 1. File->New->Project 2.Maven->J ...

  3. Spring全家桶相关文章汇总(Spring,SpringBoot,SpringData,SpringCloud)

      因为Spring框架包含的组件比较多,写的博客内容也比较多,虽然有分专栏但是依然不方便查找,所以专门用一篇文章来记录相关文章,会不定期更新. 一.Spring 1.基础内容 Spring介绍 Sp ...

  4. be of + 名词

    语法: “be of +抽象名词(词组)” 表示主语的某种形状或特征,相当于 "be+形容词" 例如: be of value=be valuable  : be of inter ...

  5. CSPS_114

    考前自闭赛 综合我100场血的教训,我的考试策略应该是: 1.不要期望能AC某道题,想都不要想,否则很容易直接崩 2.哪怕想到正解,先打暴力,把暴力码出来!没用也码! 稳扎稳打地得到代码难度最小的下一 ...

  6. python 判断操作系统以及操作系统版本号

    >>> import platform >>> platform.platform() 'Darwin-17.7.0-x86_64-i386-64bit' > ...

  7. 「NOIP2016」换教室

    传送门 Description 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 $ 2n $ 节课程安排在 $ n $ 个时间段上.在第 $ i ...

  8. python: isdigit int float 使用

    >>> num1 = '2.0' >>> print num1.isdigit() False >>> num2 = ' >>> ...

  9. 树形dp专题总结

    树形dp专题总结 大力dp的练习与晋升 原题均可以在网址上找到 技巧总结 1.换根大法 2.状态定义应只考虑考虑影响的关系 3.数据结构与dp的合理结合(T11) 4.抽直径解决求最长链的许多类问题( ...

  10. SQLSERVER|CDC日志变更捕获机制

    一.什么是CDC? 变更数据捕获(Change Data Capture ,简称 CDC)记录 SQL Server 表的插入.更新和删除活动.SQLServer的操作会写日志,这也是CDC捕获数据的 ...