Heim >Backend-Entwicklung >PHP-Tutorial >Um mit rauen Netzwerkumgebungen klarzukommen, legen Sie Timeout-Limits für php-curl fest, um ein Einfrieren des Servers zu verhindern.
Das Projekt zur Suche nach ausländischen Gütern kann nicht eingereicht werden, da kein Firmenname vorhanden ist. Daher wird die Front-End-Maschine im Alibaba Cloud Hong Kong ECS platziert und ein anderes Alibaba Cloud Hangzhou ECS ist für die Ausführung von crontab——Crawler ausführen, Bilder speichern in Alibaba Cloud OSS usw. In letzter Zeit habe ich das Gefühl, dass Hangzhou ECS etwas überflüssig ist (ursprünglich gab es ein Hangzhou RDS, aber ich habe vor, es zu entfernen, also habe ich das gesamte crontab auf Hangzhou ECS verschoben). Zurück zum Hong Kong ECS zum Laufen. Es verursachte viele Probleme. Welches Problem hat es verursacht? Das Kernproblem besteht darin, dass sich Hong Kong ECS in einer internationalen Netzwerkumgebung befindet und beim Zugriff auf Server auf dem Festland häufig Netzwerkjitter auftritt, was sehr unlösbar ist. Genauer gesagt, wenn Hong Kong ECS Alibaba Cloud Hangzhou
abfragt (open search
es gibt keinen Hong Kong-Knoten, Liebes╥﹏╥...), wird häufig ein Fehler gemeldet dass Hong Kong ECS das Bild erfasst und es dann auf Hangzhou OSS hochlädt ( OSS hat einen Hong Kong-Knoten, aber das Problem ist, dass es keinen Bildverarbeitungsdienst gibt. Halten Sie das nicht für eine Abzocke?) Zweitens , es ist langsam. Es bleibt oft eine Weile hängen, bevor ein Fehler gemeldet wird, was die Upload-Effizienz extrem niedrig macht. Aus diesem Grund gibt es einen Rückstand von Tausenden von gecrawlten Produkten, die darauf warten, Bilder hochzuladen, bevor sie kann in die Regale gestellt werden.) Das Problem von open search
ist immer noch leicht zu lösen. Das SDK bietet eine Timeout-Konfiguration, die etwas größer ist (5 Sekunden), und es wird grundsätzlich kein Fehler gemeldet. open search
Das OSS SDK bietet diese Konfiguration überhaupt nicht. Um dieses Problem zu lösen, habe ich beschlossen, tief in das SDK einzusteigen und den Quellcode zu ändern.
Das SDK von OSS fordert die API über
an. Nach einer Untersuchung habe ich festgestellt, dass dieses SDK eine Datei mit dem Namen php-curl
hat, die eine Klasse requestcore.class.php
definiert. Offensichtlich ist diese Klasse für das Senden von Requested verantwortlich. Unter diesen ist RequestCore
für die Konfiguration von Curl verantwortlich, und prep_request()
ist für die Ausführung von Curl verantwortlich (d. h. für das tatsächliche Senden der Anfrage). send_request($parse = false)
Werfen wir zunächst einen Blick auf
, das zwei Timeout-Konfigurationen von zwei prep_request()
enthält: php-curl
und CURLOPT_TIMEOUT
CURLOPT_CONNECTTIMEOUT
curl_setopt($curl_handle, CURLOPT_TIMEOUT, 5184000);curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 120);
Einfach zu verstehen, es ist das Timeout-Limit des gesamten Curl-Anfrageprozesses (http-Anfrage und -Antwort) in Sekunden. Auf 0 gesetzt bedeutet keine Begrenzung. CURLOPT_TIMEOUT
ist schwer zu verstehen. Es ist derzeit bestätigt, dass dies ein kleiner Teil des Curl-Anfrageprozesses ist, daher muss es kleiner als CURLOPT_CONNECTTIMEOUT
eingestellt werden, andernfalls ist CURLOPT_TIMEOUT
bedeutungslos. Die Informationen im Internet besagen Folgendes: CURLOPT_TIMEOUT
CURLOPT_CONNECTTIMEOUT Die Zeit, die vor dem Herstellen einer Verbindung gewartet werden soll. Wenn sie auf 0 gesetzt ist, wird auf unbestimmte Zeit gewartet.Dieser
ist eher vage. Ich beziehe mich eher auf die Zeit, die zum Abschluss des 发起连接前等待的时间
-Prozesses benötigt wird, oder mit anderen Worten, der gesamte Prozess von TCP三次握手
muss innerhalb abgeschlossen werden TCP三次握手
Innerhalb von 12 Sekunden abschließen, andernfalls kommt es zu einer Zeitüberschreitung. CURLOPT_CONNECTTIMEOUT
Wenn der Vorgang nicht innerhalb der angegebenen Zeit abgeschlossen werden kann, bedeutet dies, dass der Server ausgelastet ist/abstürzt oder das Netzwerk abnormal ist, was mit dem in diesem Artikel erwähnten Szenario übereinstimmt. TCP三次握手
Basierend auf dieser Vermutung habe ich
auf 3 Sekunden gesetzt: CURLOPT_CONNECTTIMEOUT
curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 3);Das ist es. Es gibt keine Sie müssen 2 Minuten warten, wenn das Netzwerk zittert (die SDK-Einstellung
ist 120 Sekunden), bevor Sie einen Fehler melden. CURLOPT_CONNECTTIMEOUT
verwenden, aber laut Brother Niao weist diese Konfiguration Fehler auf und wurde nicht getestet. „Curls Millisekunden-Timeout“ „Bug“》CURLOPT_TIMEOUT_MS