PHP解決高並發問題
我們知道在多執行緒寫入同一個檔案的時候,會存有「執行緒安全」的問題(多個執行緒同時執行同一段程式碼,如果每次執行結果和單執行緒運行的結果是一樣的,結果和預期相同,就是執行緒安全的)。如果是MySQL資料庫,可以使用它自帶的鎖定機制很好的解決問題,但是,在大規模並發的場景中,是不建議使用MySQL的。
秒殺和搶購的場景中,還有另一個問題,就是“超發”,如果在這方面控制不慎,會產生發送過多的情況。我們也曾經聽說過,某些電商搞搶購活動,買家成功拍攝後,商家卻不承認訂單有效,拒絕出貨。這裡的問題,也許不一定是商家姦詐,而是系統技術層面有超發風險所導致的。
1、悲觀鎖定思路
解決線程安全的思路很多,可以從「悲觀鎖」的方向開始討論。
悲觀鎖,也就是在修改資料的時候,採用鎖定狀態,排除外部請求的修改。遇到加鎖的狀態,就必須等待。
雖然上述的方案的確解決了線程安全的問題,但是,別忘記,我們的場景是「高並發」。也就是說,會很多這樣的修改請求,每個請求都需要等待“鎖”,某些線程可能永遠沒有機會搶到這個“鎖”,這種請求就會死在那裡。
同時,這種請求會很多,瞬間增加系統的平均回應時間,結果是可用連線數被耗盡,系統陷入異常。
2、FIFO佇列思路
那好,那麼我們稍微修改一下上面的場景,我們直接將請求放入佇列中的,採用FIFO(First Input First Output,先進先出),這樣的話,我們就不會導致某些請求永遠取得不到鎖。看到這裡,是不是有點強行把多線程變成單線程的感覺哈。
然後,我們現在解決了鎖定的問題,全部要求採用「先進先出」的佇列方式來處理。那麼新的問題來了,高並發的場景下,因為請求很多,很可能一瞬間將隊列內存“撐爆”,然後系統又陷入到了異常狀態。
或設計一個極大的記憶體佇列,也是一種方案,但是,系統處理完一個佇列內請求的速度根本無法和瘋狂湧入佇列中的數目相比。也就是說,佇列內的請求會越累積越多,最終Web系統平均回應時候還是會大幅下降,系統還是陷入異常。
3、檔案鎖的想法
對於日IP不高或說並發數不是很大的應用,一般不用考慮這些!用一般的文件操作方法完全沒有問題。但如果並發高,在我們對文件進行讀寫操作時,很有可能多個進程對進一文件進行操作,如果這時不對文件的訪問進行相應的獨佔,就容易造成數據丟失
最佳化方案4:使用非阻塞的檔案排他鎖
<?php //优化方案4:使用非阻塞的文件排他锁 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); ?>
以上內容僅供參考!
推薦教學:PHP影片教學
#以上是php是怎麼解決高併發的的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本文比較了酸和基本數據庫模型,詳細介紹了它們的特徵和適當的用例。酸優先確定數據完整性和一致性,適合財務和電子商務應用程序,而基礎則側重於可用性和

本文討論了確保PHP文件上傳的確保,以防止諸如代碼注入之類的漏洞。它專注於文件類型驗證,安全存儲和錯誤處理以增強應用程序安全性。

本文討論了在PHP中實施API速率限制的策略,包括諸如令牌桶和漏水桶等算法,以及使用Symfony/Rate-limimiter之類的庫。它還涵蓋監視,動態調整速率限制和手

本文討論了使用password_hash和pyspasswify在PHP中使用密碼的好處。主要論點是,這些功能通過自動鹽,強大的哈希算法和SECH來增強密碼保護

本文討論了OWASP在PHP和緩解策略中的十大漏洞。關鍵問題包括注射,驗證損壞和XSS,並提供用於監視和保護PHP應用程序的推薦工具。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

WebStorm Mac版
好用的JavaScript開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Dreamweaver Mac版
視覺化網頁開發工具

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。