wake-up-neo.net

Debuggen von Timeout-Fehlern in PHP (Laravel)?

Ich erhalte Berichte über viele Fehler, auf die Kunden gestoßen sind

Symfony\Component\Debug\Exception\FatalErrorException

Maximale Ausführungszeit von 30 Sekunden überschritten

Ich selbst kann es weder auf meinem lokalen Computer noch auf dem Produktionsserver replizieren. Die URLs hierfür sind alle auf der Website vorhanden. Ich denke, es ist etwas Globales, wie eine Middleware, die dies verursacht.

Ich benutze Sentry.io , um die Daten zu sammeln, aber der Exception-Trace hat nur einen Eintrag, der auf einen bestimmten Code im Basiscode von Symfony verweist.

vendor/symfony/Finder/Iterator/ExcludeDirectoryFilterIterator.php in Zeile 73

vendor/symfony/Finder/Iterator/DateRangeFilterIterator.php in Zeile 45

anbieter/symfony/Finder/Iterator/RecursiveDirectoryIterator.php in Zeile 69

Offensichtlich scheint es etwas zu geben, das mit dem Dateisystem zu tun hat, aber da keine Spur vorhanden ist, kann ich nicht sehen, wo ich nach dem Fehler im Site-Code suchen soll. Ich würde vermuten, es ist eine Art Endlosschleife oder Leck, aber es gibt keine Spur, die man sehen könnte, und keine konsistente Methode, um das Problem zu reproduzieren.

Wie soll ich nach dem Problem suchen und dieses debuggen?

Gibt es irgendwelche Einstellungen, die ich festlegen oder Werkzeuge, die ich verwenden/aktivieren könnte?

7
Giedrius

Es sieht so aus, als ob PHP auf eine Ressource wartet, zB. Dateizugriff, Datenbank, Mailserver (ich denke, Datei).

  • Haben Sie versucht, Ihre App auf einer Registerkarte mit vielen Registerkarten zu verwenden?
  • Haben Sie versucht, sich von vielen Computern aus bei demselben Konto anzumelden?
  • Vielleicht öffnet ein Teil des Skripts die Datei und schließt sie nicht?
  • Haben Sie Benutzeraktionen beim Öffnen der Site nachverfolgt, um diesen Fehler zu erhalten?
  • Überprüfen Sie Ihre Produktionsdatenbank - haben Sie möglicherweise eine sehr geringe Anzahl von Verbindungen?

EDIT

Ich sehe, dass Sie die dannyvankooten/vat.php-Bibliothek verwenden, die einige Anfragen an externe Dienste stellt. Dies kann eine Quelle Ihrer Probleme sein. Diese Bibliothek stellt Anforderungen mit curl. Der Autor setzt CURLOPT_CONNECTTIMEOUT, aber CURLOPT_TIMEOUT ist nicht festgelegt, und Ihr Skript kann manchmal länger warten, als durch die max_execution_time-Einstellung begrenzt ist.

2
arczinosek

Ich bin nicht an Laravel gewöhnt, aber ich hatte dieses Problem, wo ich es mit PHP's register_shutdown_function gelöst habe.

Ich habe festgestellt, dass es sehr nützlich ist, um Fehler zu finden, die zufällig auftreten. So mache ich das in meinem Code. Sie könnten dies irgendwo in einer gemeinsamen Datei ablegen, die auf jeder Seite ausgeführt werden würde. Index.php wäre eine gute Option für Sie, da alle Laravel -Routen es durchlaufen (meine Annahme).

register_shutdown_function( "check_for_fatal" );

function check_for_fatal(){
    $time = time(); //time when this error occurred

    $error = error_get_last();
    if (in_array($error["type"], [E_ERROR, E_CORE_ERROR, E_RECOVERABLE_ERROR])){
        $email_body = [];
        $email_body[] = 'Date: ' . date('m-d-Y H:i:s', $time);
        ob_start();
        var_dump($error);
        $email_body[] = ob_get_clean();
        //include any other data as needed
        //$body[] = "add data as appropriate";

        //You can email it to yourself, but if there are lots of errors you will be bombarded with emails
        mail('[email protected]', 'Subject', implode("\r\n", $email_body));
       //or you can save this to some log file
    }
}
2
Sheikh Azad

Nachdem ich Ihre Chat-Konversation gelesen hatte, sah ich, dass Sie diese .env-Konfiguration verwenden:

CACHE_DRIVER=file 
SESSION_DRIVER=file 

Ich denke, das ist das Problem ... ich erkläre es mir etwas besser.

Wenn Sie den file-Treiber für den Cache oder die Sitzung verwenden, erstellt Laravel Tonnen von Dateien, in denen Benutzer Sitzungsdaten oder Anwendungscache-Daten gespeichert werden. 

Wenn Ihr E-Commerce wächst und viel Datenverkehr erzeugt, kann sich die Leistung aufgrund der Unmengen von Dateien, die vom Framework gescannt werden müssen, verlangsamen.

Ich denke, das können zwei mögliche Lösungen sein:

  • Ihre Produktionsumgebung muss aktualisiert werden (ich kenne Ihre Produktionsserverspezifikationen nicht oder ob Sie über ausreichende Ressourcen verfügen).
  • Der Dateitreiber wird für Ihre Anwendungsanforderungen zu langsam.

Normalerweise verwende ich redis als Cache- und Sitzungstreiber, es ist schneller und mit einer guten Strategie für "intelligentes Caching" ein großartiges Werkzeug.

Ich denke, Sie sollten versuchen, es so gut wie möglich zu verwenden. Memcached kann auch eine gute Lösung sein. 

2
IlGala

Wenn Sie sich über den Grund der Ausnahme nicht sicher sind, können Sie auf zwei Arten damit umgehen

1 Anforderungszeitlimit erhöhen Ini_set ('max_execution_time', 60); // 60 Sekunden = 1 Minute

2 Packen Sie Ihren Code in try catch ein

try{
  //logic goes here
}catch(\Excaption $e){
 Log::error($e->getMessage().' '. $e->getFile().' '. $e->getLine());
 return back()->with('error',$e->getMessage() );
}
2
Afraz Ahmad

Können Sie eine Shutdown-Funktion registrieren? Die Shutdown-Funktion wird auch bei einem Timeout aufgerufen. Damit können Sie das, was Sie möchten, in einer Protokolldatei drucken oder speichern. Ich bin nicht sicher, ob es einen besseren Weg gibt, den Rückweg in Laravel zu erhalten, aber so würde ich es wahrscheinlich in reinem PHP tun (Aufruf von debug_backtrace).

<?php

function timedOut() {
    //save to a log file instead of printing
    var_dump(debug_backtrace());
}

register_shutdown_function("timedOut");

http://php.net/manual/de/function.register-shutdown-function.php

http://php.net/manual/de/function.debug-backtrace.php

2
elitepc

Ich habe laravel-debugbar installiert. Ich denke es hilft dir.

composer erfordern barryvdh/laravel-debugbar Als nächstes öffnen Sie die Datei config/app.php und fügen Sie im Array der Provider Folgendes hinzu:

Barryvdh\Debugbar\ServiceProvider::class,

in der Alias-Array-Klasse:

'Debugbar' => Barryvdh\Debugbar\Facade::class,

und Sie können sehen 

Debugbar::measure('My long operation', function() {

// Etwas tun…});

0
betovaz81

Es gibt keine Möglichkeit, dies in einem Try-Catch zu erfassen, da es sich hierbei eher um einen PHP-Fehler als um eine Ausnahme handelt.

Um dies zu debuggen, haben Sie mehrere Möglichkeiten:

  1. Fügen Sie dem Code einige Protokolle hinzu, um zu ermitteln, wo das Zeitlimit auftritt
  2. Sie können das Laravel Dump-Serverpaket verwenden, um Protokolle auszugeben. Dies wird tatsächlich mit Laravel 5.7 ausgeliefert, aber Sie können das Paket immer noch hinzufügen
0
Paras

Ich denke nicht, dass Sie das Timeout gerade noch erhöhen sollten. Wenn Sie "Try Catch" ausführen, können Sie das zugrunde liegende Problem verstehen. Wenn nicht, überprüfen Sie die Operationen/Funktionen, die in der jeweiligen Methode oder Klasse ausgeführt werden. Es besteht die Möglichkeit, dass Sie eine große Tabelle abfragen und versuchen, die Informationen zu verwenden.

wenn Sie tun 

\DB::listen(function ($sql) {
        var_dump($sql);
   });

dadurch erhalten Sie einen Hinweis darauf, wie viele Abfragen für den Vorgang ausgeführt werden

0
Yoweli Kachala

Sie können den php-Timeout-Fehler nicht abfangen. Dieser Fehler tritt auf, wenn der PHP-Interpreter die Ausführung anhält. Sie können das Zeitlimit beispielsweise nur ini_set ('max_execution_time', 300) erhöhen oder lange Ausführungsarbeit in einen Cron-Job, z. B. einen Laravel-Task-Zeitplan, konvertieren.

0
Ismail Zafar