php 使用redis鎖限制併發訪問類

2021-09-08 19:10:52 字數 2390 閱讀 1935

對於一些需要限制同乙個使用者併發訪問的場景,如果使用者併發請求多次,而伺服器處理沒有加鎖限制,使用者則可以多次請求成功。

例如換領優惠券,如果使用者同一時間併發提交換領碼,在沒有加鎖限制的情況下,使用者則可以使用同乙個換領碼同時兌換到多張優惠券。

偽**如下:

if

a(可以換領)

b(執行換領)

c(更新為已換領)

d(結束)

如果使用者併發提交換領碼,都能通過可以換領(a)的判斷,因為必須有乙個執行換領(b)後,才會更新為已換領(c)。因此如果使用者在有乙個更新為已換領之前,有多少次請求,這些請求都可以執行成功。 

使用檔案鎖可以實現併發訪問限制,但對於分布式架構的環境,使用檔案鎖不能保證多台伺服器的併發訪問限制。

redis是乙個開源的使用ansi c語言編寫、支援網路、可基於記憶體亦可持久化的日誌型、key-value資料庫,並提供多種語言的api。 

本文將使用其setnx方法實現分布式鎖功能。setnx即setitn**ot ex**ists。 

當鍵值不存在時,插入成功(獲取鎖成功),如果鍵值已經存在,則插入失敗(獲取鎖失敗)

redislock.class.php

<?php/**

* redis鎖操作類

* date: 2016-06-30

* author: fdipzone

* ver: 1.0

* * func:

* public lock 獲取鎖

* public unlock 釋放鎖

* private connect 連線 */

class redislock

/*** 獲取鎖

* @param string $key 鎖標識

* @param int $expire 鎖過期時間

* @return boolean

*/public

function lock($key, $expire=5)

}return

$is_lock? true : false

; }

/*** 釋放鎖

* @param string $key 鎖標識

* @return boolean

*/public

function unlock($key

) /**

* 建立redis連線

* @return link

*/private

function

connect()

$redis->select($this->_config['index']);

}catch(redi***ception $e

)

return

$redis

; }

} //

class end

?>

demo.php

<?php

require 'redislock.class.php';

$config = array

( 'host' => 'localhost',

'port' => 6379,

'index' => 0,

'auth' => '',

'timeout' => 1,

'reserved' => null,

'retry_interval' => 100,);

//建立redislock物件

$oredislock = new redislock($config

);//

定義鎖標識

$key = 'mylock';

//獲取鎖

$is_lock = $oredislock->lock($key, 10);

if($is_lock

)else

?>

測試方法:

開啟兩個不同的瀏覽器,同時在a,b中訪問demo.php 

如果先訪問的會獲取到鎖 

輸出get lock success 

do sth.. 

success

另乙個獲取鎖失敗則會輸出request too frequently

保證同一時間只有乙個訪問有效,有效限制併發訪問。 

為了避免系統突然出錯導致死鎖,所以在獲取鎖的時候增加乙個過期時間,如果已超過過期時間,即使是鎖定狀態都會釋放鎖,避免死鎖導致的問題。

php 使用redis鎖限制併發訪問類

對於一些需要限制同乙個使用者併發訪問的場景,如果使用者併發請求多次,而伺服器處理沒有加鎖限制,使用者則可以多次請求成功。例如換領優惠券,如果使用者同一時間併發提交換領碼,在沒有加鎖限制的情況下,使用者則可以使用同乙個換領碼同時兌換到多張優惠券。偽 如下 if a 可以換領 b 執行換領 c 更新為已...

php 使用redis鎖限制併發訪問類

對於一些需要限制同乙個使用者併發訪問的場景,如果使用者併發請求多次,而伺服器處理沒有加鎖限制,使用者則可以多次請求成功。例如換領優惠券,如果使用者同一時間併發提交換領碼,在沒有加鎖限制的情況下,使用者則可以使用同乙個換領碼同時兌換到多張優惠券。偽 如下 if a 可以換領 b 執行換領 c 更新為已...

php 使用redis鎖限制併發訪問類

對於一些需要限制同乙個使用者併發訪問的場景,如果使用者併發請求多次,而伺服器處理沒有加鎖限制,使用者則可以多次請求成功。例如換領優惠券,如果使用者同一時間併發提交換領碼,在沒有加鎖限制的情況下,使用者則可以使用同乙個換領碼同時兌換到多張優惠券。偽 如下 if a 可以換領 b 執行換領 c 更新為已...