2012-04-05 3 views
5

According to the documentation:Echt max_execution_time für PHP auf Linux

max_execution_time only affect the execution time of the script itself. 
Any time spent on activity that happens outside the execution of the script 
such as system calls using system(), stream operations, database queries, etc. 
is not included when determining the maximum time that the script has been running. 
This is not true on Windows where the measured time is real. 

Dies wird durch Tests bestätigt:

Wird Wird nicht

<?php 
set_time_limit(5); 
$sql = mysqli_connect('localhost','root','root','mysql'); 
$query = "SELECT SLEEP(10) FROM mysql.user;"; 
$sql->query($query) or die($query.'<br />'.$sql->error); 
echo "You got the page"; 

Timeout Timeout

<?php 
set_time_limit(5); 
while (true) { 
    // do nothing 
} 
echo "You got the page"; 

Unser Problem ist, dass wir wirklich möchten, dass PHP nach einer bestimmten Zeit aussetzt, unabhängig davon, was es tut (wir wollen die Ressourcen nicht belasten, wenn wir wissen, dass wir keine Seite geliefert haben) in einer akzeptablen Zeit, wie 10 Sekunden). Wir wissen, dass wir mit Einstellungen wie dem MySQL wait_timeout für die SQL-Abfragen spielen können, aber das Seitentimeout hängt von der Anzahl der Abfragen ab, die ausgeführt werden.

Einige Leute haben versucht, mit workarounds zu kommen, und es scheint nicht implementierbar.

F: Gibt es eine einfache Möglichkeit, eine echte PHP max_execution_time auf Linux zu bekommen, oder sind wir besser Timing an anderer Stelle aus, wie Apache Ebene?

Antwort

5

Dies ist ein ziemlich heikelen Ratschläge, aber es wird auf jeden Fall tun was Sie wollen, wenn Sie bereit sind, PHP zu modifizieren und neu zu kompilieren.

Werfen Sie einen Blick auf den PHP-Quellcode unter https://github.com/php/php-src/blob/master/Zend/zend_execute_API.c (die Datei ist Zend/zend_execute_API.c), bei Funktion zend_set_timeout. Dies ist die Funktion, die das Zeitlimit implementiert. Hier ist, wie es funktioniert auf verschiedenen Plattformen:

  • auf Windows, einen neuen Thread erstellen, starten Sie einen Timer auf, und wenn es fertig ist, setzen Sie eine globale Variable namens timed_out bis 1, die PHP-Ausführungskern überprüft diese Variable für jede Anweisung, tritt dann (sehr vereinfacht)

  • auf Cygwin, verwenden itimer mit ITIMER_REAL, die Echt Zeit, einschließlich Schlaf misst, warten, was auch immer, dann heben ein Signal die jede unterbrechen Verarbeitung und Verarbeitung stoppen

  • Verwenden Sie auf anderen Unix-Systemen itimer mit ITIMER_PROF, das nur die CPU-Zeit misst, die vom aktuellen Prozess verbraucht wird (aber sowohl im Benutzermodus als auch im Kernelmodus). Das heißt, das Warten auf andere Prozesse (wie MySQL) zählt nicht dazu.

Nun, was Sie tun möchten, ist die itimer auf Linux wechseln von ITIMER_PROF ITIMER_REAL, was natürlich manuell tun müssen, neu kompilieren, installieren usw.Der andere Unterschied zwischen diesen beiden ist, dass sie auch andere Signale verwenden, wenn der Timer abgelaufen ist. So ist mein Vorschlag, die ifdef zu ändern:

# ifdef __CYGWIN__ 

in

# if 1 

, so dass Sie sowohl ITIMER_REAL und das Signal gesetzt, dass PHP zu SIGALRM wartet.

Wie auch immer diese ganze Idee ist ungeprüft (ich verwende es für ein sehr spezifisches System, wo ITIMER_PROF defekt ist, und es scheint zu funktionieren), nicht unterstützt, etc. Verwenden Sie es auf eigene Gefahr. Es kann mit PHP selbst funktionieren, aber es könnte andere Module in PHP und in Apache brechen, wenn sie aus irgendeinem Grund das SIGALRM-Signal oder einen anderen Timer verwenden.

-2

Von httpd.conf:

Timeout: Die Anzahl der Sekunden erhält vor und sendet eine Auszeit

Timeout 300

+1

Dies wird nicht Auswirkungen auf PHP-Verarbeitung – kuba

+0

in der Tat habe ich mit Apache 'TimeOut' auf' 2' (Sekunden) eingestellt und es hat einfach keinen Effekt überhaupt. Gibt es etwas anderes als 'mod_reqtimeout', das du John empfehlen kannst? – Max

1

Dies ist eine alte und beantwortete Frage. Aber um anderen zu helfen, wollte ich auf die Option request_terminate_timeout php-fpm hinweisen. Wenn Sie PHP-FPM verwenden, ist es wahrscheinlich das, was Sie brauchen.

Wenn diese Option aktiviert ist, können Sie PHP-FPM anweisen, eine Anfrage nach N Sekunden zu beenden, unabhängig davon, was PHP tut.

Weitere Informationen finden Sie unter http://php.net/manual/en/install.fpm.configuration.php#request-terminate-timeout.

Verwandte Themen