From 728dbd5147e4344f66c67caed475af12bc88d07c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=99=AF=E9=98=B3?= <1656488874@qq.com> Date: Tue, 10 Dec 2019 09:22:09 +0800 Subject: [PATCH] =?UTF-8?q?fix=20=E5=90=8C=E6=AD=A5=E9=94=81=E5=8F=AF?= =?UTF-8?q?=E8=83=BD=E5=BC=82=E5=B8=B8=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/database/redis.go | 35 +++++++++++++++++++++++++---------- backend/services/node.go | 5 +++-- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/backend/database/redis.go b/backend/database/redis.go index 54f716d0..b165aaa3 100644 --- a/backend/database/redis.go +++ b/backend/database/redis.go @@ -155,42 +155,57 @@ func Sub(channel string, consume ConsumeFunc) error { return nil } +// 构建同步锁key func (r *Redis) getLockKey(lockKey string) string { lockKey = strings.ReplaceAll(lockKey, ":", "-") return "nodes:lock:" + lockKey } -func (r *Redis) Lock(lockKey string) error { +// 获得锁 +func (r *Redis) Lock(lockKey string) (int64, error) { c := r.pool.Get() defer utils.Close(c) lockKey = r.getLockKey(lockKey) - ts := time.Now() - v, err := c.Do("SET", lockKey, ts, "NX", "PX", 30000) + ts := time.Now().Unix() + ok, err := c.Do("SET", lockKey, ts, "NX", "PX", 30000) if err != nil { log.Errorf("get lock fail with error: %s", err.Error()) debug.PrintStack() - return err + return 0, err } - if err == nil && v == nil { + if err == nil && ok == nil { log.Errorf("the lockKey is locked: key=%s", lockKey) - return errors.New("the lockKey is locked") + return 0, errors.New("the lockKey is locked") } - return nil + return ts, nil } -func (r *Redis) UnLock(lockKey string) { +func (r *Redis) UnLock(lockKey string, value int64) { c := r.pool.Get() defer utils.Close(c) lockKey = r.getLockKey(lockKey) - v, err := c.Do("DEL", lockKey) + getValue, err := redis.Int64(c.Do("GET", lockKey)) + if err != nil { + log.Errorf("get lockKey error: %s", err.Error()) + debug.PrintStack() + return + } + + if getValue != value { + log.Errorf("the lockKey value diff: %d, %d", value, getValue) + return + } + + v, err := redis.Int64(c.Do("DEL", lockKey)) if err != nil { log.Errorf("unlock failed, error: %s", err.Error()) debug.PrintStack() return } - if v.(int64) == 0 { + + if v == 0 { log.Errorf("unlock failed: key=%s", lockKey) return } diff --git a/backend/services/node.go b/backend/services/node.go index 26cd3b89..36934746 100644 --- a/backend/services/node.go +++ b/backend/services/node.go @@ -96,10 +96,11 @@ func UpdateNodeStatus() { func handleNodeInfo(key string, data Data) { // 添加同步锁 - if err := database.RedisClient.Lock(key); err != nil { + v, err := database.RedisClient.Lock(key) + if err != nil { return } - defer database.RedisClient.UnLock(key) + defer database.RedisClient.UnLock(key, v) // 更新节点信息到数据库 s, c := database.GetCol("nodes")