分布式鎖在后臺應(yīng)用廣泛月腋,搶票系統(tǒng),秒殺系統(tǒng)都能看到它的身影瓣赂,實現(xiàn)分布式鎖的方式有很多榆骚,比如zookeeper,redis煌集,以及etcd妓肢。下面用一個簡單的用例來說明etcd的實現(xiàn)。
package main
import (
"context"
"fmt"
"github.com/coreos/etcd/clientv3"
"github.com/coreos/etcd/clientv3/concurrency"
"log"
"time"
)
func main() {
cli,err := clientv3.New(clientv3.Config{
Endpoints: []string{"localhost:12379", "localhost:22379", "localhost:32379"},
AutoSyncInterval: 0,
DialTimeout: 5 * time.Second,
DialKeepAliveTime: 0,
DialKeepAliveTimeout: 0,
MaxCallSendMsgSize: 0,
MaxCallRecvMsgSize: 0,
TLS: nil,
Username: "",
Password: "",
RejectOldCluster: false,
DialOptions: nil,
Context: nil,
})
if err != nil{
log.Fatal("err:",err.Error())
}
// 創(chuàng)建兩個單獨的會話用來演示鎖競爭
s1,err := concurrency.NewSession(cli)
if err != nil{
log.Fatal(err)
}
defer s1.Close()
m1 := concurrency.NewMutex(s1,"/my-lock/")
s2,err := concurrency.NewSession(cli)
if err != nil{
log.Fatal(err)
}
defer s2.Close()
m2 := concurrency.NewMutex(s2,"/my-lock/")
// 會話s1獲取鎖
if err := m1.Lock(context.TODO());err != nil{
log.Fatal(err)
}
m2Locked := make(chan struct{})
go func() {
defer close(m2Locked)
// 等待直到會話s1釋放了/my-lock/的鎖
if err := m2.Lock(context.TODO());err != nil{
log.Fatal(err)
}
fmt.Println("m2 locked")
}()
if err := m1.Unlock(context.TODO());err != nil{
log.Fatal(err)
}
fmt.Println("released lock for s1")
<- m2Locked
fmt.Println("acquired lock for s2")
}