溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

etcd租約機(jī)制及自動(dòng)過(guò)期的實(shí)例分析

發(fā)布時(shí)間:2022-01-07 21:48:47 來(lái)源:億速云 閱讀:772 作者:柒染 欄目:編程語(yǔ)言

這篇文章給大家介紹etcd租約機(jī)制及自動(dòng)過(guò)期的實(shí)例分析,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

對(duì)于實(shí)現(xiàn)分布式樂(lè)觀鎖非常重要。如果鎖了,突然宕機(jī)了,鎖是需要自動(dòng)釋放的。所以這鎖在etcd里是需要生命期的。
過(guò)期演示:

package main

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

func main() {
    var (
        config  clientv3.Config
        client  *clientv3.Client
        err     error
        lease clientv3.Lease
        leaseGrantResp *clientv3.LeaseGrantResponse
        leaseId clientv3.LeaseID
        putResp *clientv3.PutResponse
        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
    }

    //申請(qǐng)一個(gè)lease(租約)
    lease = clientv3.NewLease(client)

    //申請(qǐng)一個(gè)5秒的租約
    if leaseGrantResp, err = lease.Grant(context.TODO(), 5); err != nil {
        fmt.Println(err)
        return
    }

    //拿到租約的id
    leaseId = leaseGrantResp.ID

    //獲得kv api子集
    kv = clientv3.NewKV(client)

    //put一個(gè)kv,讓它與租約關(guān)聯(lián)起來(lái),從而實(shí)現(xiàn)10秒后自動(dòng)過(guò)期
    if putResp, err = kv.Put(context.TODO(), "/cron/lock/job1", "", clientv3.WithLease(leaseId)); err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("寫入成功:", putResp.Header.Revision)

    //定時(shí)看key過(guò)期沒(méi)
    for {
        if getResp, err = kv.Get(context.TODO(), "/cron/lock/job1"); err != nil {
            fmt.Println(err)
            return
        }
        if getResp.Count == 0 {
            fmt.Println("kv過(guò)期了")
            break
        }
        fmt.Println("還沒(méi)過(guò)期:", getResp.Kvs)
        time.Sleep(time.Second)
    }
}

[root@bogon etcd]# go run demo6.go
寫入成功: 27
還沒(méi)過(guò)期: [key:"/cron/lock/job1" create_revision:27 mod_revision:27 version:1 lease:7587837741646622005 ]
還沒(méi)過(guò)期: [key:"/cron/lock/job1" create_revision:27 mod_revision:27 version:1 lease:7587837741646622005 ]
還沒(méi)過(guò)期: [key:"/cron/lock/job1" create_revision:27 mod_revision:27 version:1 lease:7587837741646622005 ]
還沒(méi)過(guò)期: [key:"/cron/lock/job1" create_revision:27 mod_revision:27 version:1 lease:7587837741646622005 ]
還沒(méi)過(guò)期: [key:"/cron/lock/job1" create_revision:27 mod_revision:27 version:1 lease:7587837741646622005 ]
還沒(méi)過(guò)期: [key:"/cron/lock/job1" create_revision:27 mod_revision:27 version:1 lease:7587837741646622005 ]
kv過(guò)期了
[root@bogon etcd]#

申請(qǐng)一把分布式鎖的時(shí)候,是誰(shuí)搶到了key就是搶到了鎖,如果不主動(dòng)釋放這鎖,按道理講不應(yīng)該讓租約過(guò)期,租約過(guò)期主要是為了程序宕掉之后,鎖自動(dòng)釋放,防止程序異常退出。如果程序搶到了這個(gè)鎖,我們希望鎖一直不失效,知道我們主動(dòng)釋放它:

package main

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

func main() {
    var (
        config  clientv3.Config
        client  *clientv3.Client
        err     error
        lease clientv3.Lease
        leaseGrantResp *clientv3.LeaseGrantResponse
        leaseId clientv3.LeaseID
        putResp *clientv3.PutResponse
        kv clientv3.KV
        getResp *clientv3.GetResponse
        keepResp *clientv3.LeaseKeepAliveResponse
        keepRespChan <-chan *clientv3.LeaseKeepAliveResponse //只讀channel
    )

    //客戶端配置
    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
    }

    //申請(qǐng)一個(gè)lease(租約)
    lease = clientv3.NewLease(client)

    //申請(qǐng)一個(gè)5秒的租約
    if leaseGrantResp, err = lease.Grant(context.TODO(), 5); err != nil {
        fmt.Println(err)
        return
    }

    //拿到租約的id
    leaseId = leaseGrantResp.ID

    //(自動(dòng)續(xù)租)當(dāng)我們申請(qǐng)了租約之后,我們就可以啟動(dòng)一個(gè)續(xù)租
    if keepRespChan, err = lease.KeepAlive(context.TODO(), leaseId); err != nil {
        fmt.Println(err)
        return
    }

    //處理續(xù)租應(yīng)答的協(xié)程
    go func() {
        for {
            select {
            case keepResp = <-keepRespChan:
                if keepRespChan == nil {
                    fmt.Println("租約已經(jīng)失效")
                    goto END
                } else { //每秒會(huì)續(xù)租一次,所以就會(huì)受到一次應(yīng)答
                    fmt.Println("收到自動(dòng)續(xù)租應(yīng)答:", keepResp.ID)
                }
            }
        }
        END:
    }()

    //獲得kv api子集
    kv = clientv3.NewKV(client)

    //put一個(gè)kv,讓它與租約關(guān)聯(lián)起來(lái),從而實(shí)現(xiàn)10秒后自動(dòng)過(guò)期
    if putResp, err = kv.Put(context.TODO(), "/cron/lock/job1", "", clientv3.WithLease(leaseId)); err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("寫入成功:", putResp.Header.Revision)

    //定時(shí)看key過(guò)期沒(méi)
    for {
        if getResp, err = kv.Get(context.TODO(), "/cron/lock/job1"); err != nil {
            fmt.Println(err)
            return
        }
        if getResp.Count == 0 {
            fmt.Println("kv過(guò)期了")
            break
        }
        fmt.Println("還沒(méi)過(guò)期:", getResp.Kvs)
        time.Sleep(time.Second)
    }
}

[root@bogon etcd]# go run demo7.go
寫入成功: 30
收到自動(dòng)續(xù)租應(yīng)答: 7587837741646622039
還沒(méi)過(guò)期: [key:"/cron/lock/job1" create_revision:29 mod_revision:30 version:2 lease:7587837741646622039 ]
還沒(méi)過(guò)期: [key:"/cron/lock/job1" create_revision:29 mod_revision:30 version:2 lease:7587837741646622039 ]
收到自動(dòng)續(xù)租應(yīng)答: 7587837741646622039
還沒(méi)過(guò)期: [key:"/cron/lock/job1" create_revision:29 mod_revision:30 version:2 lease:7587837741646622039 ]
還沒(méi)過(guò)期: [key:"/cron/lock/job1" create_revision:29 mod_revision:30 version:2 lease:7587837741646622039 ]
還沒(méi)過(guò)期: [key:"/cron/lock/job1" create_revision:29 mod_revision:30 version:2 lease:7587837741646622039 ]
收到自動(dòng)續(xù)租應(yīng)答: 7587837741646622039
還沒(méi)過(guò)期: [key:"/cron/lock/job1" create_revision:29 mod_revision:30 version:2 lease:7587837741646622039 ]
還沒(méi)過(guò)期: [key:"/cron/lock/job1" create_revision:29 mod_revision:30 version:2 lease:7587837741646622039 ]
收到自動(dòng)續(xù)租應(yīng)答: 7587837741646622039
......

關(guān)于etcd租約機(jī)制及自動(dòng)過(guò)期的實(shí)例分析就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI