redis實(shí)現(xiàn)的分布式鎖

使用redis實(shí)現(xiàn)的分布式鎖,真正想要分布式鎖還是用zk做好,redis的實(shí)現(xiàn)還是有風(fēng)險(xiǎn),簡(jiǎn)單用用還可以。

  1. redis集群中根據(jù)key進(jìn)行哈希分配到不同的hash槽,如果某個(gè)槽的機(jī)器down了,相當(dāng)于這些key都解鎖了。
  2. 如果程序執(zhí)行時(shí)間過長(zhǎng),鎖就被自動(dòng)釋放了。而且也不可能不加過期時(shí)間,否則剛加完鎖,機(jī)器down了,這個(gè)鎖就永遠(yuǎn)得不到釋放
  3. 使用zk的話,通過臨時(shí)節(jié)點(diǎn)加watcher可以完美避開redis分布式鎖的這些問題,就是加鎖解鎖寫起來比較復(fù)雜
  • 使用redis實(shí)現(xiàn)的分布式鎖主要有兩點(diǎn)要注意:1.對(duì)redis的操作保持原子。2.保持誰加的鎖誰釋放。原理比較簡(jiǎn)單,不用細(xì)說了
    private static final int LOCK_SECOND = 60;
    private static final String UNLOCK_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
    private static final String LOCK_SUCC = "OK";
    private static final Long UNLOCK_SUCC = 1L;

    public String lock(String key) {
        if (StringUtils.isBlank(key)) {
            return StringUtils.EMPTY;
        }
        key = StringAssist.joinUnderline(RedisKey.DISTRIBUTED_LOCK_PRE, key);
        String uuid = UUID.randomUUID().toString();
        try (Jedis jedis = pool.getResource()) {
            String setRet = jedis.set(key, uuid, "NX", "EX", LOCK_SECOND);
            if (StringUtils.equals(setRet, LOCK_SUCC)) { // 設(shè)置成功
                return uuid;
            }
            // 設(shè)置失敗
            return StringUtils.EMPTY;
        } catch (Exception e) {
            log.error("lock error, key:{}", key, e);
            return StringUtils.EMPTY;
        }
    }

    public boolean unlock(String key, String uuid) {
        if (StringUtils.isAnyBlank(key, uuid)) {
            return false;
        }
        key = StringAssist.joinUnderline(RedisKey.DISTRIBUTED_LOCK_PRE, key);
        try (Jedis jedis = pool.getResource()) {
            Object result = jedis.eval(UNLOCK_SCRIPT, Collections.singletonList(key), Collections.singletonList(uuid));
            if (UNLOCK_SUCC.equals(result)) {
                return true;
            }
            return false;
        } catch (Exception e) {
            log.error("unlock error, key:{}", key, e);
            return false;
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容