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

2021-09-10 16:38:54 字數 4301 閱讀 1718

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

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

偽**如下:

if a(可以換領)

b(執行換領)

c(更新為已換領)

d(結束)

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

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

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

本文將使用其setnx方法實現分布式鎖功能。setnx即set it not exists。

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

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

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

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

再分享一下我老師大神的人工智慧教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智慧的隊伍中來!

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

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

偽**如下:

if a(可以換領)

b(執行換領)

c(更新為已換領)

d(結束)

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

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

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

本文將使用其setnx方法實現分布式鎖功能。setnx即set it not exists。

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

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 更新為已...