package main
import (
goredislib "github.com/go-redis/redis/v8"
"github.com/go-redsync/redsync/v4"
"github.com/go-redsync/redsync/v4/redis/goredis/v8"
)
func main() {
// Create a pool with go-redis (or redigo) which is the pool redisync will
// use while communicating with Redis. This can also be any pool that
// implements the `redis.Pool` interface.
client := goredislib.NewClient(&goredislib.Options{
Addr: "localhost:6379",
})
pool := goredis.NewPool(client) // or, pool := redigo.NewPool(...)
// Create an instance of redisync to be used to obtain a mutual exclusion
// lock.
rs := redsync.New(pool)
// Obtain a new mutex by using the same name for all instances wanting the
// same lock.
mutexname := "my-global-mutex"
mutex := rs.NewMutex(mutexname)
// Obtain a lock for our given mutex. After this is successful, no one else
// can obtain the same lock (the same mutex name) until we unlock it.
if err := mutex.Lock(); err != nil {
panic(err)
}
// Do your work that requires the lock.
// Release the lock so other processes or threads can obtain a lock.
if ok, err := mutex.Unlock(); !ok || err != nil {
panic("unlock failed")
}
}
redsync源码解读
setnx的作用
将获取和设置值变成原子性的操作
如果我的服务挂掉了- 死锁
- 设置过期时间
- 如果你设置了过期时间,那么如果过期时间到了我的业务逻辑没有执行完怎么办?
- 在过期之前刷新一下
- 需要自己去启动协程完成延时的工作
- 延时的接口可能会带来负面影响 - 如果其中某一个服务hung住了, 2s就能执行完,但是你hung住那么你就会一直去申请延长锁,导致别人永远获取不到锁,这个很要命
分布锁需要解决的问题 - lua脚本去做
- 互斥性 - setnx
- 死锁
- 安全性
- 锁只能被持有该锁的用户删除,不能被其他用户删除
- 当时设置的value值是多少只有当时的g才能知道
- 在删除的时取出redis中的值和当前自己保存下来的值对比一下
- 锁只能被持有该锁的用户删除,不能被其他用户删除
- 即使你这样实现了分布式但是还是会有问题 - redlock