模擬準(zhǔn)備–如何模擬高并發(fā)訪問一個(gè)腳本:apache安裝文件的bin/ab.exe可以模擬并發(fā)量 -c 模擬多少并發(fā)量 -n 一共請求多少次 http://請求的腳本
例如:cmd: apache安裝路徑/bin/ab.exe -c 10 -n 10 http://web.test.com/test.php
【切入正題】
mysql中的鎖:
語法 :
lock table 表名1 read|write, 表名2 read|write ……………… 【鎖表】
unlock tables? 【釋放表】
Read:讀鎖|共享鎖 : 所有的客戶端只能讀這個(gè)表不能寫這個(gè)表
Write:寫鎖|排它鎖: 所有當(dāng)前鎖定客戶端可以操作這個(gè)表,其他客戶端只能阻塞
注意:在鎖表的過程中只能操作被鎖定的表,如果要操作其他表,必須把所有要操作的表都鎖定起來!
PHP中的文件鎖 (鎖的是文件,不是表)
文件鎖的文件與表有什么關(guān)系?:一點(diǎn)關(guān)系也沒有,與令牌相似,誰拿到誰操作。所以表根本沒鎖。
測試時(shí),有個(gè)文件就行,叫什么名無所謂
總結(jié):
項(xiàng)目中應(yīng)該只使用PHP中的文件鎖,盡量避免鎖表,因?yàn)槿绻肀绘i定了,那么整個(gè)網(wǎng)站中所有和這個(gè)表相關(guān)的功能都被拖慢了(例如:前臺很多用戶一直下訂單,商品表mysql鎖表,其他與商品表相關(guān)的操作一直處于阻塞狀態(tài)【讀不出來商品表】,因?yàn)橐粋€(gè)功能把整個(gè)網(wǎng)站速度拖慢)。
我的一個(gè)項(xiàng)目就是O2O外賣,中午12-2點(diǎn),晚上6點(diǎn)都是訂單高并發(fā)時(shí),這種情況下,MySQL鎖顯然是不考慮的,用戶體驗(yàn)太差。其實(shí)根據(jù)實(shí)際的需求,外賣可以不用設(shè)計(jì)庫存量的,當(dāng)然除了秒殺活動模塊還是需要php文件鎖的。
應(yīng)用場景:
1. 高并發(fā)下單時(shí),減庫存量時(shí)要加鎖
2. 高并發(fā)搶單、搶票時(shí)要使用
MySQL鎖示例代碼:
<?php /** 模擬秒殺活動-- 商品100件 CREATE TABLE a ( id int comment '模擬100件活動商品的數(shù)量' ); INSERT INTO a VALUES(100); 模仿:以10的并發(fā)量訪問這個(gè)腳本! 使用apache自帶的ab.exe軟件 */ error_reporting(0); mysql_connect('localhost','root','admin123'); mysql_select_db('test'); # mysql 鎖 mysql_query('LOCK TABLE a WRITE');// 只有一個(gè)客戶端可以鎖定表,其他客戶端阻塞在這 $rs = mysql_query('SELECT id FROM a'); $id = mysql_result($rs, 0, 0); if($id >?0) { ????--$id; ????mysql_query('UPDATE?a?SET?id='.$id); } #?mysql?解鎖 mysql_query('UNLOCK?TABLES');
PHP文件鎖示例代碼:
<?php /** 模擬秒殺活動-- 商品100件 CREATE TABLE a ( id int comment '模擬100件活動商品的數(shù)量' ); INSERT INTO a VALUES(100); 模仿:以10的并發(fā)量訪問這個(gè)腳本! 使用apache自帶的ab.exe軟件 */ error_reporting(0); mysql_connect('localhost','root','admin123'); mysql_select_db('test'); # php中的文件鎖 $fp = fopen('./a.lock', 'r'); // php的文件鎖和表沒關(guān)系,隨便一個(gè)文件即可 flock($fp, LOCK_EX);// 排他鎖 $rs = mysql_query('SELECT id FROM a'); $id = mysql_result($rs, 0, 0); if($id >?0) { ????--$id; ????mysql_query('UPDATE?a?SET?id='.$id); } #?php的文件鎖,釋放鎖 flock($fp,?LOCK_UN); fclose($fp);