最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

php基于redis的分布式鎖實例詳解

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

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

redis鎖失效的情況:

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

set cache_key random_seed NX PX 30000

上面這個set命令拆解開就是:

setnx cache_key random_seed 
expire cache_key 30

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

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

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

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

釋放鎖的操作有三步:

get 所持有鎖
判斷這個鎖是否自己所持有
刪除持有鎖
所以,這三步要保證原子性。用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í)行的時候,需要把前面的隨機(jī)數(shù)作為argv[1] 的值傳進(jìn)去,把cache_key作為keys[1]的值傳進(jìn)去。

public class RedisLockHelper {
  @Resource
  private R2mClusterClient r2mClusterClient;

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

  /**
   * 刪除指定key value
   * 如果 r2m中 key 對應(yīng)的value==value  返回 1
   * 如果 r2m中 key 對應(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的分布式鎖實例詳解的文章就介紹到這了,更多相關(guān)php基于redis的分布式鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • PHP實現(xiàn)小程序批量通知推送

    PHP實現(xiàn)小程序批量通知推送

    這篇文章主要為大家詳細(xì)介紹了PHP實現(xiàn)小程序批量通知推送,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • 一篇文章弄懂PHP和HTML的嵌套寫法

    一篇文章弄懂PHP和HTML的嵌套寫法

    雖然HTML標(biāo)簽有很多,并且我們在制作頁面的時候可以無限的嵌套,但是嵌套也有規(guī)則,不能隨意的嵌套,這篇文章主要給大家介紹了如何通過一篇文章弄懂PHP和HTML的嵌套寫法,需要的朋友可以參考下
    2021-07-07
  • 解決在laravel中auth建立時候遇到的問題

    解決在laravel中auth建立時候遇到的問題

    今天小編就為大家分享一篇解決在laravel中auth建立時候遇到的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-10-10
  • php cookie 詳解使用實例

    php cookie 詳解使用實例

    這篇文章主要介紹了php cookie 詳解使用實例的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • 淺談PHP的反射API

    淺談PHP的反射API

    PHP5添加了一項新的功能:Reflection。這個功能使得phper可以reverse-engineer class, interface,function,method and extension。通過PHP代碼,就可以得到某object的所有信息,并且可以和它交互。
    2017-02-02
  • yii數(shù)據(jù)庫的查詢方法

    yii數(shù)據(jù)庫的查詢方法

    這篇文章主要介紹了yii數(shù)據(jù)庫的查詢方法,結(jié)合實例簡單分析了直接查詢和使用criteria進(jìn)行查詢的技巧,需要的朋友可以參考下
    2015-12-12
  • PHP中子類重載父類的方法【parent::方法名】

    PHP中子類重載父類的方法【parent::方法名】

    這篇文章主要介紹了PHP中子類重載父類的方法【parent::方法名】的相關(guān)內(nèi)容,小編本文講述的還不錯,所有分享給大家,供大家參考
    2016-05-05
  • Zend Framework入門教程之Zend_Session會話操作詳解

    Zend Framework入門教程之Zend_Session會話操作詳解

    這篇文章主要介紹了Zend Framework入門教程之Zend_Session會話操作,結(jié)合實例形式詳細(xì)分析了Zend_Session會話操作的具體使用技巧,需要的朋友可以參考下
    2016-12-12
  • Thinkphp5.0框架使用模型Model的獲取器、修改器、軟刪除數(shù)據(jù)操作示例

    Thinkphp5.0框架使用模型Model的獲取器、修改器、軟刪除數(shù)據(jù)操作示例

    這篇文章主要介紹了Thinkphp5.0框架使用模型Model的獲取器、修改器、軟刪除數(shù)據(jù)操作,結(jié)合實例形式分析了thinkPHP5.0模型Model獲取器、修改器數(shù)據(jù)操作相關(guān)實現(xiàn)技巧與注意事項,需要的朋友可以參考下
    2019-10-10
  • laravel 解決ajax異步提交數(shù)據(jù),并還回填充表格的問題

    laravel 解決ajax異步提交數(shù)據(jù),并還回填充表格的問題

    今天小編就為大家分享一篇laravel 解決ajax異步提交數(shù)據(jù),并還回填充表格的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-10-10

最新評論

裕民县| 玛曲县| 托里县| 庄浪县| 普宁市| 泗洪县| 永靖县| 织金县| 无棣县| 拉萨市| 柳州市| 布尔津县| 横峰县| 亳州市| 岐山县| 常德市| 连南| 镇坪县| 靖安县| 广平县| 南康市| 漯河市| 上林县| 汾西县| 盐边县| 阿克苏市| 密云县| 甘泉县| 琼结县| 汨罗市| 定州市| 祁门县| 桃园市| 漯河市| 龙州县| 鹿邑县| 衡水市| 晋州市| 石首市| 石泉县| 芷江|