[zeromicro/go-zero]关于redis lock的问题请教

2024-01-17 814 views
8

如题:https://go-zero.dev/cn/redis-lock.html 这是文档中的关于redis lock的文档,其中

假如是5毫秒,业务执行需要4毫秒,这时候是没问题的,假如业务有时候需要10毫秒,这时候key已经失效了,我看源码里面没有起对应的g去做key的续期, 我自己本地改动了下源码,但是改动比较大,

type RedisLock struct {
    store   *Redis
    seconds uint32
    key     string
    id      string

      ddl     chan bool
}

func (rl *RedisLock) Acquire() (bool, error) {
    rl.ddl = make(chan bool, 1)
    rl.ddl <- false
.....

}

func (rl *RedisLock) AcquireLockWithTimeout() error {
    ticker := time.NewTicker(time.Duration(int(rl.seconds)))
    ddl := <-rl.ddl
    go func() {
        if !ddl {
            for range ticker.C {
                ttl, _ := rl.store.Ttl(rl.key)
                if ttl == -2 {
                    _, _ = rl.Acquire()
                }
            }
        }
    }()
    ticker.Stop()
    return nil
}

func (rl *RedisLock) Release() (bool, error) {
    rl.ddl <- true
    resp, err := rl.store.Eval(delCommand, []string{rl.key}, []string{rl.id})
    if err != nil {
        return false, err
    }
....
}

不知道有木有其他更好的处理办法

回答

2

不能自动续期的,如果出bug了,别人永远也拿不到锁,你总得有个时间才行。

5

@kevwan 不是可以这么写嘛?

defer func() {
  recover()
  // 3. 释放锁
  redisLock.Release()
}()

即使出了bug,然后最后兜底释放锁

2

出了bug未必是panic,可能是长时间不释放

9

万老师您的意思是,假如代码层一直比如查询db卡主等这种异常情况,长时间不释放对吧,那可以不可以就是加一个时间限制,比如5s之内不释放的话,就在不在续期

func (rl *RedisLock) AcquireLockWithTimeout() error {
    ticker := time.NewTicker(time.Duration(int(rl.seconds)))
    ddl := <-rl.ddl
    end := time.Now().Add(time.Duration(int(rl.seconds)*millisPerSecond*5 + tolerance))

    go func() {
        if !time.Now().Before(end) {
            return
        }
        if !ddl {
            for range ticker.C {
                ttl, _ := rl.store.Ttl(rl.key)
                if ttl == -2 {
                    _, _ = rl.Acquire()
                }
            }
        }
    }()
    defer ticker.Stop()
    return nil
}

这样给一个时间限制是否可以

6

那跟直接设置最初的过期时间没有区别呀

5

这个不合理 可以参考 redission 的自动锁续期

7

不做自动续期哈

5

我昨晚看了下,redission里面是watchdog +时间轮的做法,这部分的自己去实现了