Manchmal steigt die Systemlast auf einem Linux-Server, auf dem Nginx- und PHP-CGI-Webdienste (php-fpm) ausgeführt werden, an. Überprüfen Sie mit dem oberen Befehl, ob die CPU-Auslastung vieler PHP-CGI-Prozesse nahezu 100 % beträgt. Später entdeckte ich durch Nachverfolgung, dass das Auftreten einer solchen Situation eng mit der Funktion file_get_contents() von PHP zusammenhängt.
Auf großen und mittelgroßen Websites sind API-Schnittstellenaufrufe auf Basis des HTTP-Protokolls an der Tagesordnung. PHP-Programmierer verwenden gerne die einfache und praktische Funktion file_get_contents("http://example.com/"), um den zurückgegebenen Inhalt einer URL abzurufen. Wenn die Website http://example.com/ jedoch langsam reagiert, wird file_get_contents( " ) bleibt immer dort hängen und es kommt zu keiner Zeitüberschreitung.
Wir wissen, dass es in php.ini einen Parameter max_execution_time gibt, der die maximale Ausführungszeit von PHP-Skripten festlegen kann. In php-cgi (php-fpm) wird dieser Parameter jedoch nicht wirksam. Was die maximale Ausführungszeit eines PHP-Skripts wirklich steuern kann, ist der folgende Parameter in der Konfigurationsdatei php-fpm.conf:
Die Zeitüberschreitung (in Sekunden) für die Bearbeitung einer einzelnen Anfrage, nach der der Arbeitsprozess ausgeführt wird beendet
Sollte verwendet werden, wenn die INI-Option „max_execution_time“ die Skriptausführung aus irgendeinem Grund nicht stoppt
„0s“ bedeutet „aus“
Der Standardwert ist 0 Sekunden, was bedeutet, dass das PHP-Skript weiterhin ausgeführt wird. Wenn alle PHP-CGI-Prozesse in der Funktion file_get_contents() stecken bleiben, kann der Nginx-PHP-WebServer auf diese Weise keine neuen PHP-Anfragen mehr verarbeiten und Nginx gibt „502 Bad Gateway“ an den Benutzer zurück. Die Änderung dieses Parameters ist erforderlich, um die maximale Ausführungszeit eines PHP-Skripts festzulegen, behandelt jedoch nur die Symptome und nicht die Grundursache. Wenn es beispielsweise auf
Um eine vollständige Lösung zu erreichen, besteht die einzige Möglichkeit für PHP-Programmierer darin, die Gewohnheit loszuwerden, file_get_contents("http://example.com/") direkt zu verwenden, und stattdessen eine geringfügige Änderung vorzunehmen und etwas hinzuzufügen eine Zeitüberschreitung. Verwenden Sie die folgende Methode, um HTTP-GET-Anfragen zu implementieren. Wenn Sie Schwierigkeiten damit haben, können Sie den folgenden Code selbst in eine Funktion kapseln.
<?php $ctx = stream_context_create(array( 'http' => array( 'timeout' => 1 //设置一个超时时间,单位为秒 ) ) ); file_get_contents("http://example.com/", 0, $ctx); ?>
Natürlich ist dies nicht der einzige Grund, warum die CPU des PHP-CGI-Prozesses 100 % erreicht. Wie kann man also feststellen, ob dies durch die Funktion file_get_contents() verursacht wird?
Verwenden Sie zunächst den Befehl top, um den PHP-CGI-Prozess mit hoher CPU-Auslastung anzuzeigen.
oben – 10:34:18, 724 Tage, 21:01, 3 Benutzer, Belastungsdurchschnitt: 17,86, 11,16, 7,69
Aufgaben: 561 insgesamt, 15 laufend, 546 schlafend, 0 gestoppt, 0 Zombie
Cpu(s): 5,9 %us, 4,2 %sy, 0,0 %ni, 89,4 %id, 0,2 %wa, 0,0 %hi, 0,2 %si, 0,0 %st
Speicher: 8100996k gesamt, 4320108k genutzt, 3780888k frei, 772572k Puffer
Swap: 8193108k gesamt, 50776k genutzt, 8142332k frei, 412088k zwischengespeichert<.>
10745 www 18 0 360m 24m 14 m R 94,8 0,3 0: 39,51 PHP-CGI
10707 www 18 0 360m 25m 14m S 77,4 0,3 0: 33,48 PHP-CGI
10782 WWW 20 20. 20.33.48 PHP-CGI
10782 www 20 0 360m 26m 15m R 75,5 0,3 0:10,93 php-cgi 362m 28m 15m R 54,2 0,4 0: 32,65 php-cgi
10711 www 25 0 360m 25m 15 m R 52,2 0,3 0: 44,25 PHP-CGI
10688 WWW 25 0 359 m 25 m 15 m R 38,7 0,3 0: 10.44 PHP-PHP- cgi
10719 www 25 0 360m 26m 16m R 7,7 0,3 0:40,59 php-cgi用以下命令跟踪一下:
strace -p 10747
如果屏幕显示:
poll([{fd=6, events=POLLIN}], 1 , 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll( [{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select( 7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events= POLLIN}], 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd =6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [ 6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, [ 6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}] , 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0 })
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
Dann können Sie Das Problem wird definitiv durch file_get_contents() verursacht.