站長資訊網
        最全最豐富的資訊網站

        php怎樣應對高并發

        高并發下的數據安全

        我們知道在多線程寫入同一個文件的時候,會出現“線程安全”的問題(多個線程同時運行同一段代碼,如果每次運行結果和單線程運行的結果是一樣的,結果和預期相同,就是線程安全的)。

        php怎樣應對高并發

        如果是MySQL數據庫,可以使用它自帶的鎖機制很好的解決問題,但是在大規模并發的場景中,是不推薦使用MySQL的。秒殺和搶購的場景中,最關鍵的問題,就是“超發”,如果在這方面控制不慎,會導致實際產生的訂單比預售商品還多的問題。

        超發的原因:(推薦學習:PHP編程從入門到精通)

        假設某個搶購場景中,我們一共只有100個商品,在最后一刻,我們已經消耗了99個商品,僅剩最后一個。這個時候,系統發來多個并發請求,這批請求讀取到的商品余量都是1個,然后都通過了余量的判斷,最終導致超發。

        值得注意的是:記得將庫存字段number字段設為unsigned,當庫存為0時,因為unsigned字段不能為負數,將會返回false

        優化方案

        優化1:使用MySQL的事務,鎖住操作的行 BEGIN ; SELECT … FOR UPDATE ; COMMIT ; ROLLBACK

        <?php 	//優化方案1:使用MySQL的事務,鎖住操作的行 	include('./mysql.php'); 	function build_order_no(){ 		return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8); 	} 	//記錄日志 	function insertLog($event,$type=0){ 		global $conn; 		$sql="insert into ih_log(event,type) 		values('$event','$type')"; 		mysqli_query($conn,$sql); 	} 	 	mysqli_query($conn,"BEGIN");  //開始事務 	$sql="select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id' FOR UPDATE";//此時這條記錄被鎖住,其它事務必須等待此次事務提交后才能執行 	$rs=mysqli_query($conn,$sql); 	$row=$rs->fetch_assoc(); 	 	if($row['number']>0){ 		//生成訂單 		$order_sn=build_order_no(); 		$sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price) 			values('$order_sn','$user_id','$goods_id','$sku_id','$price')"; 		$order_rs=mysqli_query($conn,$sql); 		//庫存減少 		$sql="update ih_store set number=number-{$number} where sku_id='$sku_id'"; 		$store_rs=mysqli_query($conn,$sql); 		if($store_rs){ 		  echo '庫存減少成功'; 			insertLog('庫存減少成功'); 			mysqli_query($conn,"COMMIT");//事務提交即解鎖 		}else{ 		  echo '庫存減少失敗'; 			insertLog('庫存減少失敗'); 		} 	}else{ 		echo '庫存不夠'; 		insertLog('庫存不夠'); 		mysqli_query($conn,"ROLLBACK"); 	}

        優化2:文件鎖的思路

        對于日訪問量不高或者說并發數不是很大的應用,用一般的文件操作方法完全沒有問題。但如果并發高,在我們對文件進行讀寫操作時,很有可能多個進程對進一文件進行操作,如果這時不對文件的訪問進行相應的獨占,就容易造成數據丟失。

        <?php //優化方案2:使用非阻塞的文件排他鎖 	include ('./mysql.php'); 	//生成唯一訂單號 	function build_order_no(){ 	  return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8); 	}   	//記錄日志 	function insertLog($event,$type=0){ 		global $conn; 		$sql="insert into ih_log(event,type) 		values('$event','$type')"; 		mysqli_query($conn,$sql); 	} 	$fp = fopen("lock.txt", "w+"); 	if(!flock($fp,LOCK_EX | LOCK_NB)){ 		echo "系統繁忙,請稍后再試"; 		return; 	}   	//下單 	$sql="select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id'"; 	$rs =  mysqli_query($conn,$sql); 	$row = $rs->fetch_assoc(); 	if($row['number']>0){//庫存是否大于0 		//模擬下單操作 		$order_sn=build_order_no(); 		$sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price) 		values('$order_sn','$user_id','$goods_id','$sku_id','$price')"; 		$order_rs =  mysqli_query($conn,$sql); 		//庫存減少 		$sql="update ih_store set number=number-{$number} where sku_id='$sku_id'"; 		$store_rs =  mysqli_query($conn,$sql); 		if($store_rs){ 			echo '庫存減少成功'; 			insertLog('庫存減少成功'); 			flock($fp,LOCK_UN);//釋放鎖 		}else{ 			echo '庫存減少失敗'; 			insertLog('庫存減少失敗'); 		} 	}else{ 		echo '庫存不夠'; 		insertLog('庫存不夠'); 	} 	 	fclose($fp);

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 国产99视频精品专区| 99久久国产热无码精品免费久久久久| 国产欧美日韩精品a在线观看 | 久99久无码精品视频免费播放| 国内精品伊人久久久久AV影院| 日韩欧美亚洲国产精品字幕久久久 | 麻豆国产精品VA在线观看不卡| 99视频精品全部在线观看| 亚洲一日韩欧美中文字幕欧美日韩在线精品一区二 | 国产成人亚洲精品青草天美| 日本精品一区二区三区四区 | 精品免费视在线观看| 国产精品无码日韩欧| 四虎国产精品永久在线观看| 日韩亚洲精品福利 | 2021国产精品成人免费视频| 日产精品久久久一区二区| 亚洲国产精品成人| 久久精品国产72国产精福利| 国产精品国产三级在线高清观看| 老司机国内精品久久久久| 国产99精品久久| 99精品高清视频一区二区| 成人区精品一区二区不卡| 久久久久99精品成人片欧美 | 亚洲精品A在线观看| 全国精品一区二区在线观看| 久久精品三级视频| 蜜桃麻豆www久久国产精品 | 四虎国产精品免费久久5151| 国产精品视频网| 国产精品一在线观看| 好吊妞视频精品| 国产精品自拍一区| 色播精品免费小视频| 亚洲精品高清国产一久久| 一区二区三区精品国产欧美| 中文字幕亚洲精品| 国产精品美女WWW爽爽爽视频| 国产精品自在拍一区二区不卡| 精品久久久久中文字|