最近写了点ETCD的代码,记录一下关于分布式锁的点,方便查缺补漏。
编程语言为go语言,使用ETCD的话,会比较方面,使用的源码为:https://github.com/etcd-io/etcd
1. 为什么要用ETCD?
为了服务发现,假设有多个节点需要上线,需要找到这些点的话,就需要一一记录每个节点的信息状态。但如果新增节点,那么需要手动添加,告诉服务又新增了哪些节点。但如果每个节点按固定规则都会去向ETCD注册一下,那么服务只需要按改规则监控即可。
2. 为什么要使用ETCD分布式锁?
每个节点可能有一些任务需要做,若改节点down掉,那么希望其他节点可以将改节点都任务代理,但这里有且仅有一个节点代理即可。因此当节点相互监控到某个节点down掉时,需要通过竞争的方式抢到锁,进而获取任务。当然当节点恢复后,该节点还需要归还任务,并且清理痕迹,方便下次抢任务。
这里封装了一个类,寄希望与以后可以重复使用,代码如下:
package service
import (
"context"
"fmt"
"log"
"time"
"github.com/coreos/etcd/clientv3"
"github.com/coreos/etcd/clientv3/concurrency"
)
type EtcdMutex struct {
s *concurrency.Session
m *concurrency.Mutex
}
func InitEtcdMutex(client *clientv3.Client, ctx context.Context, key string) (mutex *EtcdMutex, err error) {
mutex = &EtcdMutex{}
mutex.s, err = concurrency.NewSession(client)
if err != nil {
log.Printf("concurrency create session error:%v", err)
return
}
mutex.m = concurrency.NewMutex(mutex.s, key)
return
}
func (mutex *EtcdMutex) Release() {
mutex.s.Close()
}
func (mutex *EtcdMutex) Lock(timeout int) (err error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
defer cancel()
err = mutex.m.Lock(ctx)
return
}
func (mutex *EtcdMutex) Unlock() (err error) {
err = mutex.m.Unlock(context.TODO())
return
}
代码中key是按规则设定当全局锁,代码测试可用。
go新晋小白,有不足之处望指证。