日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > php >内容正文

php

php如何防止超发,PHP+redis实现的限制抢购防止商品超发功能详解

發(fā)布時(shí)間:2024/4/18 php 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php如何防止超发,PHP+redis实现的限制抢购防止商品超发功能详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文實(shí)例講述了php+redis實(shí)現(xiàn)的限制搶購防止商品超發(fā)功能。分享給大家供大家參考,具體如下:

redis不僅僅是單純的緩存,它還有一些特殊的功能,在一些特殊場景上很好用。redis中key的原子自增incrby和判斷key不存在再寫入的setnx方法,可以有效的防止超發(fā)。

下面使用兩個(gè)不同的方式來說明利用redis做商品購買庫存數(shù)量限制。

業(yè)務(wù)場景很簡單,就是限制搶購5個(gè)商品,模擬并發(fā)請求搶購商品,每搶購一次對應(yīng)redis中的key值增加一次,通過判斷限購的數(shù)量來限制搶購,搶購成功寫入成功日志,失敗寫入失敗的信息記錄,通過記錄的數(shù)量來判斷是否超發(fā)。

文件index.php

require_once './myredis.php';

require_once './function.php';

class sendaward{

public $conf = [];

const v1 = 'way1';//版本一

const v2 = 'way2';//版本二

const amountlimit = 5;//搶購數(shù)量限制

const incramount = 1;//redis遞增數(shù)量值

//初始化調(diào)用對應(yīng)方法執(zhí)行商品發(fā)放

public function __construct($conf,$type){

$this->conf = $conf;

if(empty($type))

return '';

if($type==self::v1){

$this->way1(self::v1);

}elseif($type==self::v2){

$this->way2(self::v2);

}else{

return '';

}

}

//搶購商品方式一

protected function way1($v){

$redis = new myredis($this->conf);

$keynmae = getkeyname($v);

if(!$redis->exists($keynmae)){

$redis->set($keynmae,0);

}

$curramount = $redis->get($keynmae);

if(($curramount+self::incramount)>self::amountlimit){

writelog("沒有搶到商品",$v);

return;

}

$redis->incrby($keynmae,self::incramount);

writelog("搶到商品",$v);

}

//搶購商品方式二

protected function way2($v){

$redis = new myredis($this->conf);

$keynmae = getkeyname($v);

if(!$redis->exists($keynmae)){

$redis->setnx($keynmae,0);

}

if($redis->incrby($keynmae,self::incramount) > self::amountlimit){

writelog("沒有搶到商品",$v);

return;

}

writelog("搶到商品",$v);

}

}

//實(shí)例化調(diào)用對應(yīng)執(zhí)行方法

$type = isset($_get['v'])?$_get['v']:'way1';

$conf = [

'host'=>'192.168.0.214','port'=>'6379',

'auth'=>'test','db'=>2,

];

new sendaward($conf,$type);

文件myredis.php

/**

* @desc 自定義redis操作類

* **/

class myredis{

public $handler = null;

public function __construct($conf){

$this->handler = new redis();

$this->handler->connect($conf['host'], $conf['port']); //連接redis

//設(shè)置密碼

if(isset($conf['auth'])){

$this->handler->auth($conf['auth']); //密碼驗(yàn)證

}

//選擇數(shù)據(jù)庫

if(isset($conf['db'])){

$this->handler->select($conf['db']);//選擇數(shù)據(jù)庫2

}else{

$this->handler->select(0);//默認(rèn)選擇0庫

}

}

//獲取key的值

public function get($name){

return $this->handler->get($name);

}

//設(shè)置key的值

public function set($name,$value){

return $this->handler->set($name,$value);

}

//判斷key是否存在

public function exists($key){

if($this->handler->exists($key)){

return true;

}

return false;

}

//當(dāng)key不存在的設(shè)置key的值,存在則不設(shè)置

public function setnx($key,$value){

return $this->handler->setnx($key,$value);

}

//將key的數(shù)值增加指定數(shù)值

public function incrby($key,$value){

return $this->handler->incrby($key,$value);

}

}

文件function.php

//獲取商品key名稱

function getkeyname($v)

{

return "send_goods_".$v;

}

//日志寫入方法

function writelog($msg,$v)

{

$log = $msg.php_eol;

file_put_contents("log/$v.log",$log,file_append);

}

1.ab工具并發(fā)測試way1方法

[root@localhost oversend]# ab -c 100 -n 200 http://192.168.0.213:8083/index.php?v=way1

this is apachebench, version 2.3

copyright 1996 adam twiss, zeus technology ltd, http://www.zeustech.net/

licensed to the apache software foundation, http://www.apache.org/

benchmarking 192.168.0.213 (be patient)

completed 100 requests

completed 200 requests

finished 200 requests

server software: nginx

server hostname: 192.168.0.213

server port: 8083

document path: /index.php?v=way1

document length: 0 bytes

concurrency level: 100

time taken for tests: 0.089 seconds

complete requests: 200

failed requests: 0

write errors: 0

total transferred: 30600 bytes

html transferred: 0 bytes

requests per second: 2243.13 [#/sec] (mean)

time per request: 44.581 [ms] (mean)

time per request: 0.446 [ms] (mean, across all concurrent requests)

transfer rate: 335.16 [kbytes/sec] received

connection times (ms)

min mean[+/-sd] median max

connect: 0 6 2.2 5 17

processing: 2 28 16.3 25 55

waiting: 1 26 15.2 24 50

total: 5 34 16.3 30 60

percentage of the requests served within a certain time (ms)

50% 30

66% 35

75% 54

80% 56

90% 57

95% 60

98% 60

99% 60

100% 60 (longest request)

v1方法日志分析

[root@localhost log]# less -n way1.log

1 搶到商品

2 搶到商品

3 搶到商品

4 搶到商品

5 搶到商品

6 搶到商品

7 沒有搶到商品

8 沒有搶到商品

9 沒有搶到商品

10 沒有搶到商品

11 沒有搶到商品

12 沒有搶到商品

觀察日志發(fā)現(xiàn) 搶到商品的記錄有6條超過正常的5條,說明超發(fā)了

2.ab工具并發(fā)測試way2方法

[root@localhost oversend]# ab -c 100 -n 200 http://192.168.0.213:8083/index.php?v=way2

this is apachebench, version 2.3

copyright 1996 adam twiss, zeus technology ltd, http://www.zeustech.net/

licensed to the apache software foundation, http://www.apache.org/

benchmarking 192.168.0.213 (be patient)

completed 100 requests

completed 200 requests

finished 200 requests

server software: nginx

server hostname: 192.168.0.213

server port: 8083

document path: /index.php?v=way2

document length: 0 bytes

concurrency level: 100

time taken for tests: 0.087 seconds

complete requests: 200

failed requests: 0

write errors: 0

total transferred: 31059 bytes

html transferred: 0 bytes

requests per second: 2311.68 [#/sec] (mean)

time per request: 43.259 [ms] (mean)

time per request: 0.433 [ms] (mean, across all concurrent requests)

transfer rate: 350.58 [kbytes/sec] received

connection times (ms)

min mean[+/-sd] median max

connect: 0 6 5.4 5 13

processing: 3 31 16.6 30 70

waiting: 1 30 16.6 30 70

total: 5 37 18.5 32 82

percentage of the requests served within a certain time (ms)

50% 32

66% 41

75% 45

80% 50

90% 68

95% 80

98% 81

99% 82

100% 82 (longest request)

v2方法日志分析

[root@localhost log]# less -n v2.log

[root@localhost log]# less -n way2.log

1 搶到商品

2 搶到商品

3 搶到商品

4 搶到商品

5 沒有搶到商品

6 搶到商品

7 沒有搶到商品

8 沒有搶到商品

9 沒有搶到商品

10 沒有搶到商品

總結(jié):觀察日志可知搶到商品的日志記錄是5條并沒有超發(fā),說明利用這種方式可以限制住庫存的數(shù)量。之所以超發(fā)是因?yàn)榉椒ㄒ恢型ㄟ^加法來判斷限制條件的同時(shí),并發(fā)一大,就會越過這個(gè)判斷條件出現(xiàn)會超發(fā),redis的在這方面就體現(xiàn)優(yōu)勢了。

希望與廣大網(wǎng)友互動??

點(diǎn)此進(jìn)行留言吧!

與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的php如何防止超发,PHP+redis实现的限制抢购防止商品超发功能详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。