go任务调度5(go操作etcd)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go任务调度5(go操作etcd)相关的知识,希望对你有一定的参考价值。

连接etcd:

package main

import (
    "fmt"
    "go.etcd.io/etcd/clientv3"
    "time"
)

var (
    config clientv3.Config
    client *clientv3.Client
    err error
)

func main()  {
    //客户端配置
    config = clientv3.Config{
        Endpoints: []string{"0.0.0.0:2379"}, //集群列表
        DialTimeout: 5 * time.Second,
    }
    //建立连接
    if client, err = clientv3.New(config); err != nil {
        fmt.Println(err)
        return
    }
    client = client
}

k-v操作:

package main

import (
    "context"
    "fmt"
    "go.etcd.io/etcd/clientv3"
    //"github.com/coreos/etcd/clientv3"
    "time"
)

var (
    config  clientv3.Config
    client  *clientv3.Client
    err     error
    kv      clientv3.KV
    putResp *clientv3.PutResponse
)

func main() {
    //客户端配置
    config = clientv3.Config{
        Endpoints:   []string{"0.0.0.0:2379"}, //集群列表
        DialTimeout: 5 * time.Second,
    }
    //建立客户端
    if client, err = clientv3.New(config); err != nil {
        fmt.Println(err)
        return
    }
    //操作k-v(用于读写etcd的键值对)
    kv = clientv3.NewKV(client)
    //context.TODO()代表什么都不做,占位就可以了
    //不在这里指定clientv3.WithPrevKV(),则不能得到putResp.PrevKv.Key,putResp.PrevKv.Value
    if putResp, err = kv.Put(context.TODO(), "/cron/jobs/job1", "world", clientv3.WithPrevKV()); err != nil {
        fmt.Println(err)
    } else {
        //输出版本号
        fmt.Println("Revision:", putResp.Header.Revision)
        if putResp.PrevKv != nil {
            //输出上一个k-v
            fmt.Println(string(putResp.PrevKv.Key), ":", string(putResp.PrevKv.Value))
        }
    }
}

运行输出

[[email protected] etcd]# go run demo2.go
Revision: 19
/cron/jobs/job1 : hello
查看:
[[email protected] etcd-v3.3.12-linux-amd64]# ETCDCTL_API=3 ./etcdctl get "/cron/jobs/job1"
/cron/jobs/job1
world


get:

package main

import (
    "context"
    "fmt"
    "go.etcd.io/etcd/clientv3"
    //"github.com/coreos/etcd/clientv3"
    "time"
)

func main() {
    var (
        config  clientv3.Config
        client  *clientv3.Client
        err     error
        kv      clientv3.KV
        getResp *clientv3.GetResponse
    )

    //客户端配置
    config = clientv3.Config{
        Endpoints:   []string{"0.0.0.0:2379"}, //集群列表
        DialTimeout: 5 * time.Second,
    }
    //建立客户端
    if client, err = clientv3.New(config); err != nil {
        fmt.Println(err)
        return
    }
    //用于读写etcd的键值对
    kv = clientv3.NewKV(client)

    if getResp, err = kv.Get(context.TODO(), "/cron/jobs/job1"); err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(getResp.Kvs)
    }
}

[[email protected] etcd]# go run demo3.go
[key:"/cron/jobs/job1" create_revision:4 mod_revision:21 version:16 value:"world" ]
(create_revision:创建版本。mod_revision:修改版本。version:自从创建以来修改的次数。)

技术图片
(敲with列出所有选项)


获取指定“目录”下的kvs:

package main

import (
    "context"
    "fmt"
    "go.etcd.io/etcd/clientv3"
    //"github.com/coreos/etcd/clientv3"
    "time"
)

func main() {
    var (
        config  clientv3.Config
        client  *clientv3.Client
        err     error
        kv      clientv3.KV
        getResp *clientv3.GetResponse
    )

    //客户端配置
    config = clientv3.Config{
        Endpoints:   []string{"0.0.0.0:2379"}, //集群列表
        DialTimeout: 5 * time.Second,
    }
    //建立客户端
    if client, err = clientv3.New(config); err != nil {
        fmt.Println(err)
        return
    }
    //用于读写etcd的键值对
    kv = clientv3.NewKV(client)

    //读取/cron/jobs/为前缀的所有key
    if getResp, err = kv.Get(context.TODO(), "/cron/jobs/", clientv3.WithPrefix()); err != nil {
        fmt.Println(err)
    } else { //获取成功,我们遍历所有kvs
        fmt.Println(getResp.Kvs)
    }
}

[[email protected] etcd]# go run demo4.go
[key:"/cron/jobs/job1" create_revision:4 mod_revision:21 version:16 value:"world" key:"/cron/jobs/job2" create_revision:5 mod_revision:6 version:2 value:"changed" ]


删除:

package main

import (
    "context"
    "fmt"
    "go.etcd.io/etcd/clientv3"
    "go.etcd.io/etcd/mvcc/mvccpb"

    //"github.com/coreos/etcd/clientv3"
    "time"
)

func main() {
    var (
        config  clientv3.Config
        client  *clientv3.Client
        err     error
        kv      clientv3.KV
        delResp *clientv3.DeleteResponse
        //idx int
        kvpair *mvccpb.KeyValue
    )

    //客户端配置
    config = clientv3.Config{
        Endpoints:   []string{"0.0.0.0:2379"}, //集群列表
        DialTimeout: 5 * time.Second,
    }
    //建立客户端
    if client, err = clientv3.New(config); err != nil {
        fmt.Println(err)
        return
    }
    //用于读写etcd的键值对
    kv = clientv3.NewKV(client)

    //删除kv
    if delResp, err = kv.Delete(context.TODO(), "/cron/jobs/job2/", clientv3.WithPrevKV()); err != nil {
        fmt.Println(err)
        return
    }

    //被删除之前的value是什么
    if len(delResp.PrevKvs) != 0 { //必须有clientv3.WithPrevKV()才能获取delResp.PrevKvs
        for _, kvpair = range delResp.PrevKvs {
            fmt.Println("删除了key:", string(kvpair.Key), " value:", string(kvpair.Value))
        }
    }
}

[[email protected] etcd]# go run demo5.go
删除了key: /cron/jobs/job2 value: changed
再次运行什么也不输出,因为已经删除了:
[[email protected] etcd]# go run demo5.go
[[email protected] etcd]#
如果要删除以/cron/jobs/job2/“目录”开头的所有kv,则将clientv3.WithPrevKV()改为:clientv3.WithPrefix()。
clientv3.WithFromKey()则是删除以此开头的所有kv(kv存储是有序的)。

以上是关于go任务调度5(go操作etcd)的主要内容,如果未能解决你的问题,请参考以下文章

go任务调度6(etcd租约机制/自动过期)

go任务调度4(etcd安装和基本使用)

go任务调度3(etcd协调服务raft协议)

go任务调度11(分布式crontab架构分析)

go任务调度9(op实现分布式乐观锁)

go任务调度8(op取代get,put,delete方法)