Я получаю отчеты о множестве ошибок, с которыми сталкиваются клиенты
Symfony\Component\Debug\Exception\FatalErrorException
Maximum execution time of 30 seconds exceeded
Я сам не могу реплицировать его ни на локальном компьютере, ни на рабочем сервере. URL-адреса для этого есть по всему сайту, поэтому, я думаю, это что-то глобальное, например, промежуточное ПО, которое вызывает это.
Я использую Sentry.io для сбора данных, но трассировка исключения имеет только 1 запись, которая указывает на определенный код в базовом коде Symfony, чаще всего:
vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php at line 73
vendor/symfony/finder/Iterator/DateRangeFilterIterator.php at line 45
vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php at line 69
Очевидно, что есть что-то связанное с файловой системой, но из-за отсутствия следов я не вижу, где искать ошибку в коде сайта. Я бы предположил, что это какой-то бесконечный цикл или утечка, но нет никаких следов, чтобы посмотреть на это, и нет последовательного способа воспроизвести проблему.
Как мне искать проблему и отлаживать ее?
Могу ли я установить какие-либо настройки или инструменты, которые я могу использовать / включить?
У вас есть доступ к командной строке? Если да, вы можете попробовать strace tecmint.com/…
@ArtisticPhoenix Да, я пробовал использовать различные переменные сеанса (не вошли в систему, вошли в систему как разные пользователи). В системе нет загрузки / генерации файлов, и ошибки возникают случайным образом, когда пользователь пытается открыть даже простейшую страницу, которая извлекает некоторые базовые данные.
@ AdrianHernandez-Lopez Я попробую, спасибо.
Сообщения об ошибках обычно имеют обратную связь с основным фрагментом кода, который вызывал всю строку функций / классов, найдите место, где возникла ошибка, она почти наверняка будет в коде, который вы / кто-то написал, а не в базе кода Symfony
@RiggsFolly Как я уже упоминал, стек трассировки включает только эту последнюю часть.
Вы смотрели журнал ошибок в var/logs
@RiggsFolly Да, исключения такие же, как они собраны в Sentry, и содержат одну и ту же трассировку только с 1 элементом.
Ваша файловая система - локальная или сетевая?
@alariva Это местное
Таким образом, проблема возникает у вашего клиента только на производстве. Правильно? У вас есть или вы можете собрать точную информацию о том, когда это произойдет? Какие действия он совершал? Отметки времени? Журналы? Частота появления?
@alariva Да, у меня есть точные журналы этого события, но я не могу воспроизвести его самостоятельно, поэтому он такой случайный и сложный для отладки. У меня есть более 1000 записей о том, когда и какие URL запрашиваются. Однако я делаю тот же запрос через производственный сервер с помощью различных комбинаций переменных сеанса и получаю ошибку только один раз из тысяч запросов.
Таким образом, сужение может потребовать методической записи каждого вхождения (как ошибки, так и успеха) одного и того же действия триггера, а затем сравнения условий контекста. Если это файловая система, знаете ли вы, работает ли ваш хост на hdd или sdd? Есть ли вероятность сбоя HW или раздела?
@alariva Я попытался сделать быстрый сценарий, который отправлял бы x запросов на URL, но это не оказалось эффективным (все запросы прошли). Он размещен на серверах AWS, поэтому я бы подумал, что у них будут проверки отказов жесткого диска. Я проверю приборную панель на предмет чего-нибудь в этом переулке, но это очень долгий путь: /
Я вижу. Можете ли вы предоставить какую-либо справочную информацию о том, что делает приложение и какие операции выполняет пользователь при возникновении проблемы?
@alariva Приложение представляет собой чрезвычайно простой сайт электронной коммерции, где люди выбирают продукт и платят за него. Это сложная вещь, проблема возникает по всем видам запросов, включая простое открытие домашней страницы, получение информации об их заказе и даже некоторые запросы AJAX (для получения корзины и т. д.).
Похоже на проблему ввода-вывода, которая может возникнуть при попытке доступа к кешу или любому другому ресурсу на диске. Я также считаю, что это странно на aws, но на данный момент мы не можем отказаться от этого. Вы можете опубликовать свой .env? (Сначала удалите все токены и учетные данные) и composer.json?
Позвольте нам продолжить обсуждение в чате.
Я думаю, вы делаете какой-то вызов API, который вызывает проблему.
@Giedrius Есть новости по этой проблеме? Также, пожалуйста, укажите в вопросе ваш полный стек разработчика.
Привет, сейчас я работаю над той же проблемой. Удалось ли как-нибудь решить это случайно? Если да, не могли бы вы поделиться? Если нет, может, мы сможем сотрудничать и вместе найти ответы?
@dardvas Привет, на самом деле я не нашел четкого решения для этого, мне просто пришлось отлаживать код по крупицам, чтобы найти, где была проблема, я думаю, что в моем случае это была утечка памяти.
@Giedrius мне кажется, что в файловой системе хранится слишком много файлов кеша. Перенос их в Redis, как сказал IlGala, решил проблему. Что ж, ваш вопрос и ответы на него составляют хороший контрольный список для всех, кто сталкивается с этой проблемой :)
@dardvas Это хорошо, спасибо! Я отмечу этот ответ, так как я также считаю, что это более вероятная причина и наиболее полезный ответ.






Если вы не уверены в причине исключения, вы можете обработать его двумя способами.
1 увеличить время ожидания запроса ini_set ('max_execution_time', 60); // 60 секунд = 1 минута
2 оберните свой код в try catch
try{
//logic goes here
}catch(\Excaption $e){
Log::error($e->getMessage().' '. $e->getFile().' '. $e->getLine());
return back()->with('error',$e->getMessage() );
}
1. Я думаю, что увеличение тайм-аута может быть временным решением, но не устранит основную причину. 2. Вы хотите обернуть все приложение (в index.php или bootstrap.php)? Если это так, то это не приводит к другим результатам, одно и то же исключение просто обрабатывается вручную.
Я не думаю, что вам стоит пока увеличивать тайм-аут. если вы сделаете «попытаться поймать», вы сможете понять основную проблему. Если нет, проверьте операции / функции, выполняемые в конкретном методе или классе. Есть вероятность, что вы запрашиваете огромную таблицу и, возможно, пытаетесь использовать информацию.
если ты это сделаешь
\DB::listen(function ($sql) {
var_dump($sql);
});
это даст вам представление о том, сколько запросов выполняется для операции
Невозможно отловить это с помощью try catch, поскольку на самом деле это ошибка PHP, а не исключение.
Чтобы отладить это, у вас есть несколько вариантов:
Я установил laravel-debugbar, думаю, вам это поможет.
композитору требуется barryvdh / laravel-debugbar Затем откройте config / app.php и внутри массива «поставщиков» добавьте:
Barryvdh\Debugbar\ServiceProvider::class,
в классе массива псевдонимов:
'Debugbar' => Barryvdh\Debugbar\Facade::class,
и вы можете просмотреть
Debugbar::measure('My long operation', function() {
// Сделай что-нибудь… });
Можете ли вы зарегистрировать функцию выключения? Функция выключения вызывается даже при истечении времени ожидания. С его помощью вы можете распечатать или сохранить то, что хотите, в файл журнала. Я не уверен, есть ли лучший способ получить обратную трассировку в laravel, но я бы, вероятно, сделал это в чистом php (вызовите 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
http://php.net/manual/en/function.debug-backtrace.php
Не знал об этом, обязательно попробую. Спасибо!
Прочитав вашу беседу в чате, я увидел, что вы используете эту конфигурацию .env:
CACHE_DRIVER=file
SESSION_DRIVER=file
Думаю, в этом проблема ... Объясняюсь немного лучше.
Когда вы используете драйвер file для кеша или сеанса, Laravel создаст тонны файлов, в которых хранятся данные сеанса пользователей или данные кеша приложений ...
Если ваша электронная коммерция растет и генерирует большой трафик, возможно, что производительность снижается из-за большого количества файлов, которые необходимо сканировать фреймворком.
Я думаю, это может быть два возможных решения:
Я обычно использую Redis в качестве драйвера кэша и сеанса, он быстрее и с хорошей стратегией «умного кэширования» это отличный инструмент.
Я думаю, вам стоит попробовать использовать и его, если возможно. Memcached тоже может быть хорошим решением.
В этом есть большой смысл. Я постараюсь решить свою проблему, используя ваши ответы и ответы @elitepc (register_shudown_function), и посмотрю, к чему это меня приведет, спасибо!
вопрос: «Как отлаживать ошибки тайм-аута в PHP (Laravel)?», приложение должно работать с этой конфигурацией CACHE_DRIVER = file SESSION_DRIVER = file, конечно, лучше использовать redis, но вопрос не в этом ...
Честно говоря, вам лучше всего установить xdebug и просто отладить его по старинке, пройти весь запрос, чтобы найти узкое место, и попытаться выяснить, откуда оно взялось. Laravel, как и другие фреймворки, был разработан для максимально плавной работы. Если вы столкнулись с подобными ошибками, это означает, что вы просто что-то неправильно запрограммировали.
Также сложно дать вам конкретный совет без дополнительной информации. Я бы предложил воссоздать спецификации среды (вы можете использовать Docker или Vagrant или что-то еще, что придет вам в голову, что будет работать), с которым сталкивается ваше приложение Laravel, а затем запустить с xdebug, чтобы найти, в чем проблема.
Вы не можете поймать ошибку тайм-аута php. Эта ошибка возникает, когда интерпретатор php прекращает выполнение. Вы можете только увеличить ограничение по времени, например, ini_set ('max_execution_time', 300), или преобразовать длительную работу по выполнению в задание cron, например, расписание задач laravel.
Я не привык к Laravel, но у меня была эта проблема, и я решил ее с помощью PHP-функции register_shutdown_function.
Я обнаружил, что это очень полезно для отслеживания случайных ошибок. Вот как я это делаю в своем коде. Вы можете поместить это где-нибудь в общий файл, который будет выполняться на каждой странице, index.php будет для вас хорошим вариантом, поскольку все маршруты Laravel проходят через него (мое предположение).
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
}
}
Похоже, PHP ждет какого-то ресурса, например. файловый доступ, база данных, почтовый сервер (думаю файл).
РЕДАКТИРОВАТЬ
Я вижу, что вы используете библиотеку dannyvankooten/vat.php, которая делает некоторые запросы к внешним сервисам. Это может быть источником ваших проблем. Эта библиотека делает запросы с помощью curl. Автор устанавливает CURLOPT_CONNECTTIMEOUT, но CURLOPT_TIMEOUT не установлен, и ваш сценарий иногда может ждать дольше, чем это ограничено настройкой max_execution_time.
Новая версия часовой предоставит вам правильную трассировку стека.
Вы должны использовать версию "getsentry / sentry-php"> = "2.0"
Когда вы говорите,
I, myself, cannot replicate it on my local machine nor on the production serverвы пробовали это, используя учетную запись клиента, у которой возникли проблемы. Многие из них выглядят как итерации каталога файлов, если вы разрешите им загружать или создавать файлы, у них может быть слишком много файлов, и, имея учетную запись без них, вы не сможете воспроизвести проблему. Просто мысль.