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

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

  1. redis集群中根據(jù)key進行哈希分配到不同的hash槽诞外,如果某個槽的機器down了澜沟,相當(dāng)于這些key都解鎖了。
  2. 如果程序執(zhí)行時間過長峡谊,鎖就被自動釋放了茫虽。而且也不可能不加過期時間,否則剛加完鎖既们,機器down了濒析,這個鎖就永遠(yuǎn)得不到釋放
  3. 使用zk的話,通過臨時節(jié)點加watcher可以完美避開redis分布式鎖的這些問題啥纸,就是加鎖解鎖寫起來比較復(fù)雜
  • 使用redis實現(xiàn)的分布式鎖主要有兩點要注意:1.對redis的操作保持原子悼枢。2.保持誰加的鎖誰釋放。原理比較簡單脾拆,不用細(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)容合作請聯(lián)系作者
  • 序言:七十年代末莹妒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子绰上,更是在濱河造成了極大的恐慌旨怠,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜈块,死亡現(xiàn)場離奇詭異鉴腻,居然都是意外死亡,警方通過查閱死者的電腦和手機百揭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門爽哎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人器一,你說我怎么就攤上這事课锌。” “怎么了祈秕?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵渺贤,是天一觀的道長。 經(jīng)常有香客問我请毛,道長志鞍,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任方仿,我火速辦了婚禮固棚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘仙蚜。我一直安慰自己玻孟,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布鳍征。 她就那樣靜靜地躺著黍翎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪艳丛。 梳的紋絲不亂的頭發(fā)上匣掸,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機與錄音氮双,去河邊找鬼碰酝。 笑死,一個胖子當(dāng)著我的面吹牛戴差,可吹牛的內(nèi)容都是我干的送爸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼袭厂!你這毒婦竟也來了墨吓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤纹磺,失蹤者是張志新(化名)和其女友劉穎帖烘,沒想到半個月后秘症,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體乡摹,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年采转,在試婚紗的時候發(fā)現(xiàn)自己被綠了聪廉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡氏义,死狀恐怖锄列,靈堂內(nèi)的尸體忽然破棺而出图云,到底是詐尸還是另有隱情惯悠,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布竣况,位于F島的核電站克婶,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏情萤。R本人自食惡果不足惜摹恨,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一筋岛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧晒哄,春花似錦睁宰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春预侯,著一層夾襖步出監(jiān)牢的瞬間致开,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工雌桑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留喇喉,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓校坑,卻偏偏與公主長得像拣技,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子耍目,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容