Golang-分布式锁
·
SETNX 命令
SETNX key value :
- 如果 key 不存在,则设置成功,返回 1。
- 如果 key 已存在,则不做任何操作,返回 0。
👉 这就是实现“只有第一个人能抢到锁”的关键。
过期时间 (TTL)
给锁加上过期时间(EX 秒 或 PX 毫秒),避免死锁。比如持有锁的客户端挂掉了,Redis 会自动释放。
package redis
import (
"context"
"github.com/redis/go-redis/v9"
"time"
)
func tryLock(rc *redis.Client, key string, duration time.Duration) bool {
// 尝试获取锁
cmd := rc.SetNX(context.Background(), key, "value can any", duration)
if cmd.Err() != nil {
return false
} else {
return cmd.Val()
}
}
func releaseLock(rc *redis.Client, key string) {
// 释放分布式锁
rc.Del(context.Background(), key)
}
test:
package redis
import (
"fmt"
"sync"
"testing"
"time"
)
func TestTryLock(t *testing.T) {
clinet := newTestClient()
const P = 100 // 假设100个协程抢锁
key := "iphone秒杀活动-第2台"
defer releaseLock(clinet, key)
wg := sync.WaitGroup{}
wg.Add(P)
for i := 0; i < P; i++ {
go func(i int) {
defer wg.Done()
if tryLock(clinet, key, time.Hour) {
fmt.Printf("协程%d抢到了手机!\n", i)
} else {
fmt.Printf("协程%d没有抢到手机~\n", i)
}
}(i)
}
wg.Wait()
}

更多推荐
所有评论(0)