golang 分布式锁

Posted Witcher

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang 分布式锁相关的知识,希望对你有一定的参考价值。

随机value 防止释放其他服务的锁

import (
	"crypto/rand"
	"encoding/base64"
	"errors"
	"fmt"
	"github.com/go-redis/redis/v7"
	"time"
)

//分布式锁实现(不可重入)
type RedisLock struct {
	LockKey string
	value   string
}

//保证原子性
var delScript = `
if redis.call("get",KEY[1])==ARGV[1] then
	return redis.call("del",KEY[1])
else
	return 0
end
`

func (rl *RedisLock) Lock(client *redis.Client, timeout int) error {
	//随机数
	if client == nil {
		return errors.New("redis client is nil")
	}
	b := make([]byte, 16)
	_, err := rand.Read(b)
	if err != nil {
		return err
	}
	rl.value = base64.StdEncoding.EncodeToString(b)
	ok, err := client.SetNX(rl.LockKey, rl.value, time.Duration(timeout)*time.Second).Result()
	if err == nil && ok {
		errMsg := fmt.Sprintf("lock filed")
		return errors.New(errMsg)
	} else if err == nil {
		return nil
	} else {
		errMsg := fmt.Sprintf("redis lock fail err: %v", err)
		return errors.New(errMsg)
	}
}

//解锁
func (rl *RedisLock) Unlock(client *redis.Client) error {
	if client == nil {
		return errors.New("redis client is nil")
	}
	_, err := client.Eval(delScript, []string{rl.LockKey, rl.value}).Result()
	return err
}

以上是关于golang 分布式锁的主要内容,如果未能解决你的问题,请参考以下文章

Golang基于Mysql分布式锁实现集群主备

编程实践分布式锁的实现代码

etcd 租约Watch功能分布式锁的golang实践

基于golang实现redis分布式锁

基于golang实现redis分布式锁

基于golang实现redis分布式锁