1

我是go-redis distributed lock用来实现互斥访问的,我的服务器是单线程服务器。但同时,许多请求都获得了distributed lock.

func (redisMgrPtr *RedisMgr) getLock(key string) (int32) {
    encodeKey := transcoding.Base64Encode(key)
    _, err := redisMgrPtr.redisClient.SetNX(redisMgrPtr.ctx, 
    encodeKey, 1, TIMEOUT).Result()
    if err != nil {
        return -1
    }
    return 0
}

func (redisMgrPtr *RedisMgr) delLock(key string, sessionId string) {
    encodeKey := transcoding.Base64Encode(key)
    redisMgrPtr.redisClient.Del(redisMgrPtr.ctx, encodeKey)
    Log.Errorf("session[%s] del lock", sessionId)
}

获取锁码是这样的:

func (redisMgrPtr *RedisMgr) GetServer(name string, session string) () {
    for { 
        locRes := redisMgrPtr.getLock(name) 
        if locRes == 0 {
            break
        } else {
            time.Sleep(5 * time.Millisecond)
            continue
        }
    }
    defer redisMgrPtr.delLock(sceneLock, sessionId)
    Log.Errorf("session[%s] get lock", sessionId)
    // do something
}

我发现许多请求同时获得锁,结果是

2021-09-08T15:05:21.073+0800 session[51776955325] get lock
2021-09-08T15:05:21.073+0800 session[91776955325] get lock
2021-09-08T15:05:21.073+0800 session[71776955325] get lock

我认为同时只有一个会话可以获得锁定

4

1 回答 1

2

问题似乎与锁定功能有关。它不检查值是否存在,它只是检查错误。

func (redisMgrPtr *RedisMgr) getLock(key string) (int32) {
    encodeKey := transcoding.Base64Encode(key)
    wasSet, err := redisMgrPtr.redisClient.SetNX(redisMgrPtr.ctx, encodeKey, 1, TIMEOUT).Result()
    if err != nil || !wasSet {
        return -1
    }
    return 0
}

...或使用布尔值更容易推理:

func (redisMgrPtr *RedisMgr) getLock(key string) (ok bool) {
    encodeKey := transcoding.Base64Encode(key)
    wasSet, err := redisMgrPtr.redisClient.SetNX(redisMgrPtr.ctx, encodeKey, 1, TIMEOUT).Result()
    return err == nil && wasSet
}

使用布尔版本GetServer可能如下所示:

func (redisMgrPtr *RedisMgr) GetServer(name string, session string) () {
    for { 
        if ok := redisMgrPtr.getLock(name); ok {
            break
        }
        time.Sleep(5 * time.Millisecond)
    }
    defer redisMgrPtr.delLock(sceneLock, sessionId)
    Log.Errorf("session[%s] get lock", sessionId)
    // do something
}
于 2021-09-08T16:41:34.653 回答