欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

php基于redis的分布式鎖實(shí)例詳解

 更新時(shí)間:2021年03月05日 10:25:33   作者:PHP開發(fā)社區(qū)  
這篇文章主要介紹了php基于redis的分布式鎖實(shí)例詳解,有正好需要的可以跟著小編一起來學(xué)習(xí)下,可以讓在寫代碼上的能力更近一步

在使用分布式鎖進(jìn)行互斥資源訪問時(shí)候,我們很多方案是采用redis的實(shí)現(xiàn)。
固然,redis的單節(jié)點(diǎn)鎖在極端情況也是有問題的,假設(shè)你的業(yè)務(wù)允許偶爾的失效,使用單節(jié)點(diǎn)的redis鎖方案就足夠了,簡單而且效率高。

redis鎖失效的情況:

客戶端1從master節(jié)點(diǎn)獲取了鎖
master宕機(jī)了,存儲(chǔ)鎖的key還沒來得及同步到slave節(jié)點(diǎn)上
slave升級(jí)為master
客戶端2從新的master上獲取到同一個(gè)資源的鎖
于是,客戶端1和客戶端2同事持有了同一個(gè)資源的鎖,鎖的安全性被打破。
如果我們不考慮這種極端情況,需要實(shí)現(xiàn)一個(gè)基于單節(jié)點(diǎn)redis鎖的大致流程:

set cache_key random_seed NX PX 30000

上面這個(gè)set命令拆解開就是:

setnx cache_key random_seed 
expire cache_key 30

雖然這兩組命令執(zhí)行的效果一樣,但是第二個(gè)是非原子性操作,如果執(zhí)行了setnx成功,但是expire失敗的話,就會(huì)造成這個(gè)key一直存在了,無法釋放的情況。

redis的作者也指出,在使用單節(jié)點(diǎn)redis鎖的時(shí)候,設(shè)置一個(gè)隨機(jī)種子作為key的值是很有必要的,保證了一個(gè)客戶端釋放的鎖必須是自己所持有的那個(gè)鎖。假設(shè)獲取鎖時(shí)set的不是一個(gè)隨機(jī)數(shù),而是一個(gè)固定值,

那么可能會(huì)出現(xiàn)下面的情況:

客戶端1獲取鎖成功
客戶端1在某個(gè)操作上阻塞了很長時(shí)間
過期時(shí)間到了,鎖自動(dòng)釋放(但是在客戶端1看來自己還是持有鎖中)
客戶端2獲取到了對(duì)應(yīng)同一個(gè)資源的鎖
客戶端1從阻塞中恢復(fù)了,釋放掉自己持有的鎖,也就是釋放掉了客戶端2持有的鎖
客戶端2的鎖被客戶端1是否,失去安全性。
釋放鎖的操作,很多人直接用del命令,這會(huì)有很大的問題,保證不了這個(gè)key是被加鎖人鎖刪。這時(shí)候需要用到隨機(jī)數(shù)了。

釋放鎖的操作有三步:

get 所持有鎖
判斷這個(gè)鎖是否自己所持有
刪除持有鎖
所以,這三步要保證原子性。用lua腳本來執(zhí)行,redis官方已經(jīng)提供腳本文件。

if redis.call("get",KEYS[1]) == ARGV[1] then
  return redis.call("del",KEYS[1])
else
  return 0
end

這段腳本在執(zhí)行的時(shí)候,需要把前面的隨機(jī)數(shù)作為argv[1] 的值傳進(jìn)去,把cache_key作為keys[1]的值傳進(jìn)去。

public class RedisLockHelper {
  @Resource
  private R2mClusterClient r2mClusterClient;

  /**
   * 類似于setNx的功能,同時(shí)設(shè)置過期時(shí)間為expire毫秒
   *
   * @param key  加鎖key
   * @param value 確保在加鎖時(shí)間內(nèi)的唯一因子
   * @param expire 過期時(shí)間的毫秒數(shù)
   * @return
   */
  private String setLock(String key, String value, long expire) {
    return this.set(key, value, "NX", "PX", expire);
  }

  /**
   * 刪除指定key value
   * 如果 r2m中 key 對(duì)應(yīng)的value==value  返回 1
   * 如果 r2m中 key 對(duì)應(yīng)的value!=value  返回 0
   *
   * @param key
   * @return
   */
  private boolean atomDelete(String key, String value) {
    List<String> values = new ArrayList<>();
    values.add(value);
    String sb = "if redis.call('get',KEYS[1])==ARGV[1] then " +
        " return redis.call('del',KEYS[1]) " +
        " else " +
        " return 0" +
        " end";
    if (this.eval(sb, key, values) == 1) {
      return true;
    }
    return false;
  }

  private Long eval(String mobel, String key, List<String> value) {
    return (Long) this.r2mClusterClient.eval(mobel, key, value);
  }

  private String set(String key, String value, String nxxx, String expx, long time) {
    return this.r2mClusterClient.set(key, value, nxxx, expx, time);
  }
}

r2mClusterClient 就是jedis客戶端的封裝。

到此這篇關(guān)于php基于redis的分布式鎖實(shí)例詳解的文章就介紹到這了,更多相關(guān)php基于redis的分布式鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Laravel5.1 框架響應(yīng)基本用法實(shí)例分析

    Laravel5.1 框架響應(yīng)基本用法實(shí)例分析

    這篇文章主要介紹了Laravel5.1 框架響應(yīng)基本用法,結(jié)合實(shí)例形式分析了laravel5.1框架基本響應(yīng)、自定義響應(yīng)頭、返回值、重定向等相關(guān)使用技巧,需要的朋友可以參考下
    2020-01-01
  • thinkPHP實(shí)現(xiàn)上傳圖片及生成縮略圖功能示例

    thinkPHP實(shí)現(xiàn)上傳圖片及生成縮略圖功能示例

    這篇文章主要介紹了thinkPHP實(shí)現(xiàn)上傳圖片及生成縮略圖功能,結(jié)合實(shí)例形式分析了thinkPHP圖片上傳及縮略圖設(shè)置、生成、保存、數(shù)據(jù)庫寫入等相關(guān)操作技巧,需要的朋友可以參考下
    2017-10-10
  • PHP版微信公眾平臺(tái)紅包API

    PHP版微信公眾平臺(tái)紅包API

    這篇文章主要介紹了PHP版微信公眾平臺(tái)微信API類,目前主要實(shí)現(xiàn)了微信紅包接口,陸續(xù)會(huì)繼續(xù)進(jìn)行更新,非常的實(shí)用,這里推薦給小伙伴們,有需要的朋友可以參考下。
    2015-04-04
  • PHP讀取文件內(nèi)容的五種方式

    PHP讀取文件內(nèi)容的五種方式

    分享下php讀取文件內(nèi)容的五種方法:好吧,寫完后發(fā)現(xiàn)文件全部沒有關(guān)閉。實(shí)際應(yīng)用當(dāng)中,請(qǐng)注意關(guān)閉 fclose($fp)
    2015-12-12
  • PHP判斷JSON對(duì)象是否存在的方法(推薦)

    PHP判斷JSON對(duì)象是否存在的方法(推薦)

    這篇文章主要介紹了PHP判斷JSON對(duì)象是否存在的方法(推薦)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • Laravel異常上下文解決方案分享

    Laravel異常上下文解決方案分享

    異常處理是編程中十分重要但也最容易被人忽視的語言特性,下面這篇文章主要給大家介紹了關(guān)于Laravel異常上下文解決方案的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-01-01
  • ThinkPHP中create()方法自動(dòng)驗(yàn)證實(shí)例

    ThinkPHP中create()方法自動(dòng)驗(yàn)證實(shí)例

    下面小編就為大家?guī)硪黄猅hinkPHP中create()方法自動(dòng)驗(yàn)證實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-04-04
  • php-fpm重啟導(dǎo)致的程序執(zhí)行中斷問題詳解

    php-fpm重啟導(dǎo)致的程序執(zhí)行中斷問題詳解

    這篇文章主要給大家介紹了關(guān)于php-fpm重啟導(dǎo)致的程序執(zhí)行中斷問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • PHP獲取短鏈接跳轉(zhuǎn)后的真實(shí)地址和響應(yīng)頭信息的方法

    PHP獲取短鏈接跳轉(zhuǎn)后的真實(shí)地址和響應(yīng)頭信息的方法

    這篇文章主要介紹了PHP獲取短鏈接跳轉(zhuǎn)后的真實(shí)地址和響應(yīng)頭信息的方法,本文使用get_headers函數(shù)實(shí)現(xiàn),需要的朋友可以參考下
    2014-07-07
  • Laravel+Intervention實(shí)現(xiàn)上傳圖片功能示例

    Laravel+Intervention實(shí)現(xiàn)上傳圖片功能示例

    這篇文章主要介紹了Laravel+Intervention實(shí)現(xiàn)上傳圖片功能,結(jié)合實(shí)例形式分析了Intervention的安裝及圖片上傳功能的相關(guān)設(shè)置、使用與注意事項(xiàng),需要的朋友可以參考下
    2019-07-07

最新評(píng)論