Heim >Backend-Entwicklung >PHP-Problem >Wie löst PHP hohe Parallelität?
PHP löst Probleme mit hoher Parallelität
Wir wissen, dass es eine Frage zur „Thread-Sicherheit“ gibt, wenn mehrere Threads in dieselbe Datei schreiben ( Mehrere Threads führen denselben Code gleichzeitig aus. Wenn das Ergebnis jedes Laufs mit dem eines Einzel-Thread-Laufs übereinstimmt und das Ergebnis das gleiche ist wie erwartet, ist es threadsicher. Wenn es sich um eine MySQL-Datenbank handelt, können Sie das Problem mit einem eigenen Sperrmechanismus lösen. In großen Parallelitätsszenarien wird MySQL jedoch nicht empfohlen.
In Flash-Sales- und Rush-Sales-Szenarien gibt es ein weiteres Problem, nämlich „Over-Sending“. Wenn dieser Aspekt nicht sorgfältig kontrolliert wird, kommt es zu übermäßigem Senden. Wir haben auch gehört, dass einige E-Commerce-Unternehmen Eilkäufe durchführen. Nachdem der Käufer das Produkt erfolgreich gekauft hat, erkennt der Händler die Bestellung nicht als gültig an und weigert sich, die Ware zu liefern. Das Problem liegt hier möglicherweise nicht unbedingt darin, dass der Händler hinterhältig ist, sondern darin, dass die Gefahr einer übermäßigen Ausgabe auf der technischen Ebene des Systems besteht.
1. Pessimistische Sperrideen
Es gibt viele Ideen zur Lösung der Thread-Sicherheit, und wir können die Diskussion aus der Richtung „pessimistisch“ beginnen Verriegelung".
Pessimistisches Sperren, d. h. beim Ändern von Daten wird der Sperrstatus übernommen, um Änderungen von externen Anfragen auszuschließen. Wenn Sie auf einen gesperrten Zustand stoßen, müssen Sie warten.
Obwohl die obige Lösung das Problem der Thread-Sicherheit löst, vergessen Sie nicht, dass unser Szenario „hohe Parallelität“ ist. Mit anderen Worten, es wird viele solcher Änderungsanfragen geben, und jede Anfrage muss auf eine „Sperre“ warten. Einige Threads haben möglicherweise nie die Chance, diese „Sperre“ zu ergreifen, und solche Anfragen werden dort sterben.
Gleichzeitig wird es viele solcher Anfragen geben, die die durchschnittliche Reaktionszeit des Systems sofort erhöhen. Dadurch wird die Anzahl der verfügbaren Verbindungen erschöpft und das System fällt in eine Ausnahme .
2. Idee der FIFO-Warteschlange
Okay, dann modifizieren wir das obige Szenario leicht. Wir stellen die Anfrage direkt in die Warteschlange, indem wir FIFO (First Input First Output) verwenden. First In, First Out), in diesem Fall werden wir nicht dazu führen, dass einige Anfragen niemals die Sperre erhalten. Fühlt es sich angesichts dessen so an, als würde man Multi-Threading gewaltsam in Single-Threading umwandeln?
Dann haben wir nun das Sperrproblem gelöst und alle Anfragen werden in einer „First In, First Out“-Warteschlange verarbeitet. Dann tritt in einem Szenario mit hoher Parallelität ein neues Problem auf, da der Warteschlangenspeicher augenblicklich „explodiert“ wird und das System dann wieder in einen abnormalen Zustand gerät.
Oder das Entwerfen einer riesigen Speicherwarteschlange ist ebenfalls eine Lösung. Die Geschwindigkeit, mit der das System Anfragen in einer Warteschlange verarbeitet, kann jedoch nicht mit der Anzahl der Anfragen verglichen werden, die wie verrückt in die Warteschlange strömen. Mit anderen Worten: Es werden sich immer mehr Anfragen in der Warteschlange ansammeln. Letztendlich wird die durchschnittliche Antwortzeit des Websystems immer noch erheblich sinken und das System wird immer noch in eine Ausnahme geraten.
3. Die Idee der Dateisperre
Für Anwendungen, bei denen die tägliche IP nicht hoch ist oder die Anzahl der Parallelität nicht sehr groß ist, gibt es im Allgemeinen keine Das muss man bedenken! Mit normalen Dateimanipulationsmethoden ist das überhaupt kein Problem. Wenn jedoch die Parallelität beim Lesen und Schreiben von Dateien hoch ist, ist es sehr wahrscheinlich, dass mehrere Prozesse an der nächsten Datei arbeiten. Wenn wir zu diesem Zeitpunkt den Zugriff auf die Datei nicht monopolisieren, führt dies leicht zu Datenverlust
Optimierung 4: Nicht blockierende Datei-Exklusivsperre verwenden
<?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); ?>
Der obige Inhalt dient nur als Referenz!
Empfohlenes Tutorial: PHP-Video-Tutorial
Das obige ist der detaillierte Inhalt vonWie löst PHP hohe Parallelität?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!