Je reçois des rapports de nombreuses erreurs rencontrées par les clients
Symfony\Component\Debug\Exception\FatalErrorException
Temps d'exécution maximal de 30 secondes dépassé
Je ne peux moi-même pas le reproduire sur mon ordinateur local ni sur le serveur de production. Les URL pour cela sont partout sur le site, donc, je suppose que c'est quelque chose de global, comme un middleware qui en est la cause.
J'utilise Sentry.io pour collecter les données, mais le suivi des exceptions ne comporte qu'une entrée pointant vers un certain code du code de base Symfony
, le plus souvent:
vendor/symfony/Finder/Iterator/ExcludeDirectoryFilterIterator.php à la ligne 73
vendor/symfony/Finder/Iterator/DateRangeFilterIterator.php à la ligne 45
vendor/symfony/Finder/Iterator/RecursiveDirectoryIterator.php à la ligne 69
De toute évidence, il semble qu'il y ait quelque chose de lié au système de fichiers, mais, faute de trace, je ne vois pas où chercher l'erreur dans le code du site. J'imagine que c'est une sorte de boucle ou de fuite infinie, mais il n'y a aucune trace pour la regarder, et aucun moyen cohérent de reproduire le problème.
Comment devrais-je rechercher le problème et le déboguer?
Y a-t-il des paramètres que je pourrais définir ou des outils que je pourrais utiliser/activer?
Il semble que PHP attend une ressource, par exemple. accès au fichier, base de données, serveur de messagerie (je pense fichier).
MODIFIER
Je vois que vous utilisez la bibliothèque dannyvankooten/vat.php
qui envoie des requêtes à des services externes. Cela peut être une source de vos problèmes. Cette bibliothèque fait des demandes en utilisant curl. L'auteur définit CURLOPT_CONNECTTIMEOUT
mais CURLOPT_TIMEOUT
n'est pas défini et votre script peut parfois attendre plus longtemps que le paramètre max_execution_time
ne le limite.
Je ne suis pas habitué à Laravel mais j'ai eu ce problème où je l'ai résolu en utilisant la fonction register_shutdown_function de PHP.
Je l’ai trouvé très utile pour le suivi des erreurs qui se produisent de manière aléatoire ..__ C'est ce que je fais dans mon code. Vous pouvez mettre cela quelque part dans un fichier commun qui s'exécutera sur chaque page, index.php serait une bonne option pour vous car toutes les routes Laravel le traversent (mon hypothèse).
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
}
}
Après avoir lu votre conversation en ligne, j'ai constaté que vous utilisiez cette configuration .env
:
CACHE_DRIVER=file
SESSION_DRIVER=file
Je pense que c'est le problème ... Je m'explique un peu mieux.
Lorsque vous utilisez le pilote file
pour le cache ou la session, Laravel crée des tonnes de fichiers qui stockent les données de session des utilisateurs ou les données de cache d'application ...
Si votre commerce électronique se développe et génère beaucoup de trafic, il est possible que les performances ralentissent à cause de cette multitude de fichiers qui doivent être analysés par le cadre.
Je pense que cela peut être deux solutions possibles:
J'utilise habituellement redis en tant que cache et pilote de session, c'est plus rapide et avec une bonne stratégie de "mise en cache intelligente" c'est un excellent outil.
Je pense que vous devriez essayer de l'utiliser aussi bien si possible. Memcached peut être une bonne solution aussi.
Si vous n'êtes pas sûr de la raison de l'exception, vous pouvez la gérer de deux manières.
1 augmenter le délai de requête ini_set ('max_execution_time', 60); // 60 secondes = 1 minute
2 envelopper votre code dans try catch
try{
//logic goes here
}catch(\Excaption $e){
Log::error($e->getMessage().' '. $e->getFile().' '. $e->getLine());
return back()->with('error',$e->getMessage() );
}
Pouvez-vous enregistrer une fonction d'arrêt? La fonction d'arrêt est appelée même en cas de dépassement du délai d'attente. Avec celui-ci, vous pouvez imprimer ou enregistrer ce que vous voulez dans un fichier journal ... Je ne sais pas s'il existe un meilleur moyen de récupérer la trace dans laravel, mais c'est ce que je ferais probablement en php pur (appeler 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/en/function.register-shutdown-function.php
J'ai installé laravel-debugbar.Je pense que cela vous aidera.
composer require barryvdh/laravel-debugbar Ouvrez ensuite config/app.php et dans le tableau ‘providers’, ajoutez:
Barryvdh\Debugbar\ServiceProvider::class,
dans la classe d'alias array:
'Debugbar' => Barryvdh\Debugbar\Facade::class,
et vous pouvez voir
Debugbar::measure('My long operation', function() {
// Faire quelque chose…});
Il n'y a aucun moyen de détecter cela dans un test try, car il s'agit en réalité d'une erreur PHP plutôt que d'une exception.
Pour pouvoir déboguer ceci, vous avez deux options:
Je ne pense pas que vous devriez augmenter le délai d'attente pour l'instant. Si vous faites l'essai, vous pourrez peut-être comprendre le problème sous-jacent. Sinon, vérifiez les opérations/fonctions effectuées dans la méthode ou la classe spécifique. Il est possible que vous interrogiez une grande table et essayiez peut-être d'utiliser les informations.
si tu fais
\DB::listen(function ($sql) {
var_dump($sql);
});
cela vous donnera une indication du nombre de requêtes en cours d'exécution pour l'opération
Vous ne pouvez pas attraper l'erreur de délai d'attente php. Cette erreur se produit lorsque l'interpréteur php arrête l'exécution. Vous pouvez uniquement augmenter la limite de temps, par exemple, ini_set ('max_execution_time', 300) ou convertir un travail d'exécution longue en une tâche cron, par exemple, une planification de tâches.