Heim  >  Artikel  >  Backend-Entwicklung  >  Lösen Sie das Problem der PHP-Prozess-CPU zu 100 % – file_get_contents verursachte Probleme

Lösen Sie das Problem der PHP-Prozess-CPU zu 100 % – file_get_contents verursachte Probleme

高洛峰
高洛峰Original
2016-10-17 11:00:211431Durchsuche

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“

0s

 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 30s geändert wird und file_get_contents() langsam Webinhalte abruft, bedeutet dies, dass 150 PHP-CGI-Prozesse nur 5 Anfragen pro Sekunde verarbeiten können und WebServer ebenfalls schwer zu vermeiden ist „502 Schlechtes Gateway“.

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(  
   &#39;http&#39; => array(  
       &#39;timeout&#39; => 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<.>


PID Benutzer PR Ni Vird Res.

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


  如果屏幕显示:

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)

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.


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn