中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

go任務調度9(op實現分布式樂觀鎖)

發布時間:2020-06-24 09:11:13 來源:網絡 閱讀:633 作者:梁十八 欄目:編程語言
package main

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

func main() {
    var (
        config clientv3.Config
        client *clientv3.Client
        err error
        lease clientv3.Lease
        leaseGrantResp *clientv3.LeaseGrantResponse
        leaseId clientv3.LeaseID
        keepRespChan <-chan *clientv3.LeaseKeepAliveResponse
        keepResp *clientv3.LeaseKeepAliveResponse
        ctx context.Context
        cancelFunc context.CancelFunc
        kv clientv3.KV
        txn clientv3.Txn
        txnResp *clientv3.TxnResponse
    )

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

    // lease實現鎖自動過期(上鎖之后,如果節點宕機,鎖會一直占用,所以要過期機制,也要續租機制):
    // op操作
    // txn事務: if else then

    // 1, 上鎖 (創建租約, 自動續租, 拿著租約去搶占一個key)
    lease = clientv3.NewLease(client)

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

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

    // 準備一個用于取消自動續租的context
    ctx, cancelFunc = context.WithCancel(context.TODO())

    // 確保函數退出后, 自動續租會停止
    defer cancelFunc() //終止自動續租協程(goroutine)
    defer lease.Revoke(context.TODO(), leaseId) //告訴etcd把租約直接釋放掉,更直接,立即刪除,鎖就釋放了

    // 5秒后會取消自動續租
    if keepRespChan, err = lease.KeepAlive(ctx, leaseId); err != nil {
        fmt.Println(err)
        return
    }

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

    //  if 不存在key, then 設置它, else 搶鎖失敗
    kv = clientv3.NewKV(client)

    // 創建事務
    txn = kv.Txn(context.TODO())

    // 定義事務

    // 如果key不存在(創建版本是0說明沒有被創建)
    txn.If(clientv3.Compare(clientv3.CreateRevision("/cron/lock/job9"), "=", 0)).
        Then(clientv3.OpPut("/cron/lock/job9", "xxx", clientv3.WithLease(leaseId))).
        Else(clientv3.OpGet("/cron/lock/job9")) // 否則搶鎖失敗

    // 提交事務
    if txnResp, err = txn.Commit(); err != nil {
        fmt.Println(err)
        return // 沒有問題
    }

    // 判斷是否搶到了鎖
    if !txnResp.Succeeded {
        fmt.Println("鎖被占用:", string(txnResp.Responses[0].GetResponseRange().Kvs[0].Value))
        return
    }

    // 2, 處理業務

    fmt.Println("處理任務")
    time.Sleep(5 * time.Second)

    // 3, 釋放鎖(取消自動續租, 釋放租約)
    // 上面的defer 會把租約釋放掉, 關聯的KV就被刪除了
}

go任務調度9(op實現分布式樂觀鎖)
(右邊的先執行,左邊的后執行,左邊會提示鎖已被占用)

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

鄢陵县| 沁源县| 济宁市| 焦作市| 凤山市| 那坡县| 临沧市| 鄂伦春自治旗| 克东县| 凤山县| 余庆县| 葵青区| 白玉县| 平阴县| 阳江市| 林周县| 古丈县| 衡阳市| 东乌珠穆沁旗| 将乐县| 宿松县| 贵阳市| 义乌市| 惠水县| 青浦区| 贡山| 丹东市| 光山县| 淮北市| 上蔡县| 万盛区| 陇川县| 和林格尔县| 重庆市| 绥德县| 巴楚县| 白河县| 湟中县| 理塘县| 井研县| 新巴尔虎左旗|