03.go-redis分布式锁
# 01.redis分布式锁
https://blog.csdn.net/liyan_0816/article/details/107038116
目录结构
.
├── main.go
├── redis
│ └── redis_mutex.go
1
2
3
4
2
3
4
# 1.1 redis/redis_mutex.go
- 获取和是否redis锁
package redis
import (
"context"
"log"
"sync"
"time"
"github.com/go-redis/redis/v8"
)
var Rdb *redis.Client
var Ctx = context.Background()
var mutex sync.Mutex
func NewRedis() {
Rdb = redis.NewClient(&redis.Options{
Addr: "127.0.0.1:6379",
Password: "", // no password set
DB: 0, // use default DB
})
}
func Lock(key string) bool {
mutex.Lock()
defer mutex.Unlock()
bool, err := Rdb.SetNX(Ctx, key, 1, 10*time.Second).Result()
if err != nil {
log.Println(err.Error())
}
return bool
}
func UnLock(key string) int64 {
nums, err := Rdb.Del(Ctx, key).Result()
if err != nil {
log.Println(err.Error())
return 0
}
return nums
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 1.2 main.go
package main
import (
"fmt"
"machinery-test/redis"
"sync"
)
var wg sync.WaitGroup
// https://cloud.tencent.com/developer/article/1759185
func main() {
redis.NewRedis()
redis.Rdb.Set(redis.Ctx, "apple", 1000, 0)
// 模拟有10000各用户抢购手机
for i := 0; i < 10000; i++ {
wg.Add(1) // 启动一个goroutine就登记+1
go sale()
}
wg.Wait() // 等待所有登记的goroutine都结束
count, _ := redis.Rdb.Get(redis.Ctx, "apple").Int()
fmt.Println("苹果手机最终数量---> ", count)
}
func sale() {
for {
lock := redis.Lock("lock") // lock为锁的名字
if lock == false { // 获取锁失败,继续获取锁
fmt.Println("获取锁失败")
continue
}
count, _ := redis.Rdb.Get(redis.Ctx, "apple").Int() // 获取手机数量
if count <= 0 {
fmt.Println("手机已经售完")
} else {
redis.Rdb.Set(redis.Ctx, "apple", count-1, 0)
fmt.Println("当前库存数量", count)
}
redis.UnLock("lock")
defer wg.Done() // goroutine结束就登记-1
break
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 1.3 测试分布式锁
go run main.go
1
开启10000各携程模拟10000各用户同时抢购手机
先获取redis分布式锁,如果获取到锁
- 才能 从redis获取手机数量,并进行减一操作
- 跳出循环,并释放锁
如果获取失败锁失败,继续获取锁
运行结果如下
获取锁失败
手机已经售完
获取锁失败
手机已经售完
苹果手机最终数量---> 0
1
2
3
4
5
2
3
4
5
上次更新: 2024/3/13 15:35:10