推荐使用redis set指令的nx px选项实现单节点分布式锁,因其原子性高、代码简洁;高可用场景可选redlock算法或多节点库go-redsync;跨语言一致性需求则用goredisson。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

如果您希望使用CodeGeeX辅助编写Go语言实现的分布式锁,特别是基于Redis的Redlock或单节点SETNX方案,则需明确提示模型生成符合Go生态规范、线程安全且具备过期机制的锁代码。以下是几种可直接用于生产环境的实现方法:
一、使用Redis SETNX + EXPIRE原子指令(兼容旧版Redis)
该方法通过组合SETNX与EXPIRE命令实现加锁,虽非完全原子,但可通过短超时与重试机制规避竞态风险。适用于Redis 2.6.12以下版本或对原子性要求不极致的场景。
1、定义锁结构体,包含Redis客户端、锁键名、持有者标识(如UUID)、默认过期时间(单位秒)。
2、调用redis.Client.Do("SETNX", key, value)判断是否成功设置键值。
3、若返回1,立即执行redis.Client.Do("EXPIRE", key, ttlSeconds)设置过期时间。
4、若EXPIRE失败,主动DEL该key并返回加锁失败。
5、解锁时先GET确认value匹配,再DEL,避免误删其他协程持有的锁。
二、使用Redis SET指令的NX PX选项(推荐,Redis 2.6.12+)
该方式将加锁与过期设置合并在一条原子命令中,彻底消除SETNX+EXPIRE间的竞态窗口,是当前最主流的单节点Redis分布式锁实现方式。
1、构造SET命令参数:key、唯一value(如uuid.NewString())、"NX"(仅当key不存在时设置)、"PX"(毫秒级过期时间)。
2、调用redis.Client.Do("SET", key, value, "NX", "PX", ttlMilliseconds)。
3、若返回"OK",表示加锁成功;返回nil表示key已存在,加锁失败。
4、解锁时使用Lua脚本保证GET+DEL原子性:eval "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end" 1 key value。
三、基于Redlock算法的多节点容错锁(高可用场景)
当单Redis实例不可用会导致系统瘫痪时,Redlock通过在N个独立Redis主节点(建议≥5)上同时尝试加锁,并在多数节点成功后才视为加锁成功,提升容错能力。
1、生成唯一随机token作为锁持有者标识,长度不少于20字节。
2、对每个Redis客户端,以相同key、token、相同PX毫秒值并发执行SET命令。
3、统计成功加锁的节点数,若≥(N/2)+1且总耗时未超过锁有效时间的50%,则加锁成功。
4、锁的有效期设为原设定值减去加锁阶段总耗时,防止因网络延迟导致实际有效期严重缩水。
5、解锁时向所有节点广播Lua删除脚本,忽略返回结果。
四、使用go-redsync库封装的Redlock实现
该方法复用成熟开源库go-redsync,屏蔽底层Redlock协议细节,提供简洁API,适合快速集成且无需深度定制的项目。
1、导入github.com/go-redsync/redsync/v4及其redis适配器(如redsync.NewRedisClient)。
2、初始化redsync.NewPool,传入多个*redis.Client实例。
3、创建mutex := pool.GetMutex("resource_name", redsync.WithExpiry(8*time.Second), redsync.WithTries(3))。
4、调用mutex.Lock()获取锁,返回error为nil表示成功;调用mutex.Unlock()释放锁。
5、注意:go-redsync默认不校验锁持有者身份,若需防误删,应启用WithValue选项并确保value全局唯一。
五、使用Redisson客户端的Go绑定(跨语言一致性需求)
当系统中已存在Java服务使用Redisson实现分布式锁时,为保障锁语义一致(如看门狗自动续期、公平锁、读写锁),可选用支持Redisson协议的Go客户端(如goredisson)。
1、配置Redis地址列表及连接池参数,初始化*goredisson.Client。
2、获取RLock实例:rlock := client.GetLock("my_resource")。
3、调用rlock.Lock(10*time.Second)阻塞等待加锁,或rlock.TryLock(3*time.Second, 10*time.Second)尝试加锁。
4、加锁成功后,后台自动启动看门狗任务,每1/3租约时间续期一次。
5、必须调用rlock.Unlock()显式释放,否则看门狗将持续续期直至租约耗尽。











