AB 模擬測試秒殺

2021-07-15 17:27:56 字數 4058 閱讀 6798

簡單的乙個秒殺的測試**

1.我的環境是windows下的phpstudy,進入到apache/bin目錄裡面有個ab.exe,壓力測試命令如下

./ab.exe -c

200-n

1000

2.mysql.php**如下

正常的邏輯思維,壓力增大後,導致資料庫num欄位成為負數,將下面**貼上到自己**下測試即可。

在test資料庫下,新建乙個num(庫存)的表,id欄位int型別主鍵自增,num欄位int型別

新建乙個goods_order(訂單)的表,id欄位int主鍵自增,goods_id欄位int,user_id欄位int型別,

如果發現num欄位無法成為負數,開啟sleep(2);訪問量堆積起來即可

<?php  

header("content-type: text/html; charset=utf-8");

//pdo連線資料庫方法

$dbms='mysql'; //資料庫型別

$host='localhost'; //資料庫主機名

$dbname='test'; //使用的資料庫

$user='root'; //資料庫連線使用者名稱

$pass='root'; //對應的密碼

$dsn="$dbms:host=$host;dbname=$dbname";

try

$dbh = null;

} catch (pdoexception $e)

3.如果開啟

$sql="update num set num=num-1

where id=1

and (num -1 ) >= 0

";

經過測試num欄位最小為0,在壓力測試下**執行正常,

想要增大ab壓力併發量測試,

./ab.exe -c

500-n

1000

會出現如下(看來要去linux下搭建apache來測試了)

this is apachebench, version 2.3

<$revision: 1706008 $>

licensed to the apache software foundation,

benchmarking 192.168

.1.244 (be patient)

completed 100 requests

total of

125 requests completed

test aborted after

10 failures

apr_socket_connect(): ▒▒▒▒ŀ▒▒▒▒▒▒▒▒▒▒▒ܾ▒▒▒▒޷▒▒▒▒ӡ▒ (730061)

4.redis測試,搭建好linux下的apache後,訪問linux下的redis.php壓力測試槓槓的,不會報錯了

./ab.exe -c

1000

-n1000

此壓力下,redis資料正常,不會出現負數

<?php  

header("content-type:text/html;charset=utf-8");

$redis

=new redis();

$result

=$redis

->connect('192.168.1.233',"6379");

//$num = $redis->set("num",5);

//die;

$num

= ($redis

->get("num"));

$count

=(int)$num;

echo "總共有:"

.$count;

echo "

";

if($count

>

0)else

var_dump($num);

?>

5.以上是ab測試,現在分析**

先分析redis.php,上面的這個實現在只有乙個客戶端的時候可以執行得很好。 但是, 當多個客戶端同時對同乙個鍵進行這樣的操作時, 就會產生競爭條件。舉個例子, 如果客戶端 a 和 b 都讀取了鍵原來的值, 比如 2, 那麼兩個客戶端都會將鍵的值設為 1 , 但正確的結果應該是 0 才對。

有了 watch , 我們就可以輕鬆地解決這類問題了:

因為redis的效能很高,當num為2時,ab模擬兩個併發量後num為1,模擬兩個併發量和watch如下:

./ab.exe -c2-n

2

修復**如下,加入watch監聽,確保資料準確性

<?php

//set('num');可以在終端執行

header("content-type:text/html;charset=utf-8");

$redis = new redis();

$result = $redis->connect('192.168.1.233',"6379");

$redis->watch("num");

$num = ($redis->get("num"));

$redis->multi();

$count=(int)$num;

echo

"總共有:".$count;

echo

"";

if($count>0)else

}else

//var_dump($num);

//$redis->close();

?>

設定1000個庫存,讓1000個人去搶,196個人搶到了,資料很精準

./ab.exe -c

1000

-n1000

192.168

.1.233:6379> set

num1000

ok

192.168

.1.233:6379> get

num"804"

192.168

.1.233:6379> get order

"196"

6.分析完redis.php,我們來分析mysql.php

因為 秒殺後庫存+訂單=秒殺前庫存,所以採用也要採用事物來處理

<?php  

header("content-type: text/html; charset=utf-8");

//pdo連線資料庫方法

$dbms='mysql'; //資料庫型別

$host='localhost'; //資料庫主機名

$dbname='test'; //使用的資料庫

$user='root'; //資料庫連線使用者名稱

$pass='root'; //對應的密碼

$dsn="$dbms:host=$host;dbname=$dbname";

try catch(pdoexception $ex)

} $dbh = null;

} catch (pdoexception $e)

7.總結,以上只是解決了秒殺時候,超賣的問題,但是並未考慮秒殺效率,以及高負載,只是做了簡單測試,仍需努力學習……………….

在mysql.php中並未使用悲觀鎖,因為這樣子並未超賣,比較尷尬………….

在redis.php中使用的樂觀鎖,雖然心裡對**放心了,但是效率低了,在mysql中數量基本買完,在redis中賣出去200(20%)個左右。。。。。

在ab中測試,mysql和redis整體耗時基本類似

ab 模擬測試秒殺

1.我的環境是windows下的phpstudy,進入到apache bin目錄裡面有個ab.exe,壓力測試命令如 ab.exe c 200 n 1000 2.mysql.php 如下正常的邏輯思維,壓力增大後,導致資料庫num欄位成為負數,將下面 貼上到自己 下測試即可。在test資料庫下,新建...

模擬測試秒殺

1.我的環境是windows下的phpstudy,進入到apache bin目錄裡面有個ab.exe,壓力測試命令如下 ab.exe c 200 n 1000 2.mysql.php 如下 正常的邏輯思維,壓力增大後,導致資料庫num欄位成為負數,將下面 貼上到自己 下測試即可。在test資料庫下,...

模擬秒殺系統

一 模擬秒殺系統 使用者id userid,隨機數生成 商品id prodid,固定1001 商品庫存 key seckill 1001,value 100 redis快取 已秒殺成功使用者 key seckill 1001 user set集合 controller public class se...