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實現(xiàn)鎖自動過期(上鎖之后,如果節(jié)點宕機,鎖會一直占用,所以要過期機制,也要續(xù)租機制):
// op操作
// txn事務(wù): if else then
// 1, 上鎖 (創(chuàng)建租約, 自動續(xù)租, 拿著租約去搶占一個key)
lease = clientv3.NewLease(client)
// 申請一個5秒的租約
if leaseGrantResp, err = lease.Grant(context.TODO(), 5); err != nil {
fmt.Println(err)
return
}
// 拿到租約的ID
leaseId = leaseGrantResp.ID
// 準(zhǔn)備一個用于取消自動續(xù)租的context
ctx, cancelFunc = context.WithCancel(context.TODO())
// 確保函數(shù)退出后, 自動續(xù)租會停止
defer cancelFunc() //終止自動續(xù)租協(xié)程(goroutine)
defer lease.Revoke(context.TODO(), leaseId) //告訴etcd把租約直接釋放掉,更直接,立即刪除,鎖就釋放了
// 5秒后會取消自動續(xù)租
if keepRespChan, err = lease.KeepAlive(ctx, 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 { // 每秒會續(xù)租一次, 所以就會受到一次應(yīng)答
fmt.Println("收到自動續(xù)租應(yīng)答:", keepResp.ID)
}
}
}
END:
}()
// if 不存在key, then 設(shè)置它, else 搶鎖失敗
kv = clientv3.NewKV(client)
// 創(chuàng)建事務(wù)
txn = kv.Txn(context.TODO())
// 定義事務(wù)
// 如果key不存在(創(chuàng)建版本是0說明沒有被創(chuàng)建)
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")) // 否則搶鎖失敗
// 提交事務(wù)
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, 處理業(yè)務(wù)
fmt.Println("處理任務(wù)")
time.Sleep(5 * time.Second)
// 3, 釋放鎖(取消自動續(xù)租, 釋放租約)
// 上面的defer 會把租約釋放掉, 關(guān)聯(lián)的KV就被刪除了
}
(右邊的先執(zhí)行,左邊的后執(zhí)行,左邊會提示鎖已被占用)
創(chuàng)新互聯(lián)是一家專注于做網(wǎng)站、成都網(wǎng)站建設(shè)與策劃設(shè)計,樂清網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十余年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:樂清等地區(qū)。樂清做網(wǎng)站價格咨詢:18980820575
當(dāng)前標(biāo)題:go任務(wù)調(diào)度9(op實現(xiàn)分布式樂觀鎖)
本文地址:http://www.muchs.cn/article8/ihejop.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計公司、網(wǎng)站策劃、營銷型網(wǎng)站建設(shè)、微信小程序、微信公眾號、品牌網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)