繁体   English   中英

如何在 PHP (Laravel) 中调试“Symfony\\Component\\Debug\\Exception\\FatalErrorException”错误?

[英]How to debug "Symfony\Component\Debug\Exception\FatalErrorException" errors in PHP (Laravel)?

我收到客户遇到的许多错误的报告

Symfony\\Component\\Debug\\Exception\\FatalErrorException

超过 30 秒的最大执行时间

我自己无法在本地机器或生产服务器上复制它。 这个 URL 遍布整个站点,所以,我想这是一个全局性的东西,比如导致这种情况的中间件。

我正在使用Sentry.io收集数据,但异常跟踪只有 1 个条目指向Symfony基本代码中的某个代码,最常见的是:

vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php 第 73 行

vendor/symfony/finder/Iterator/DateRangeFilterIterator.php 第 45 行

vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php 第 69 行

显然,似乎有一些与文件系统相关的东西,但由于没有跟踪,我无法看到在站点代码中在哪里查找错误。 我猜这是某种无限循环或泄漏,但没有任何痕迹可以查看,也没有一致的方法来重现问题。

我应该如何查找问题并进行调试?

有没有我可以设置的设置,或者我可以使用/启用的工具?

阅读您的聊天对话后,我看到您正在使用此.env配置:

CACHE_DRIVER=file 
SESSION_DRIVER=file 

我认为这就是问题所在……我更好地解释了自己。

当您将file驱动程序用于缓存或会话时,Laravel 将创建大量文件来存储用户会话数据或应用程序缓存数据...

如果您的电子商务正在增长并产生大量流量,那么性能可能会因为必须由框架扫描的大量文件而变慢。

我认为这可能是两种可能的解决方案:

  • 您的生产环境必须升级(我不知道您的生产服务器规格或您是否有足够的资源)。
  • 文件驱动程序对于您的应用程序要求来说变得太慢了。

我通常使用redis作为缓存和会话驱动程序,它速度更快,并且具有“智能缓存”的好策略,这是一个很棒的工具。

我认为如果可能的话,您也应该尝试使用它。 Memcached也可能是一个很好的解决方案。

如果您不确定异常的原因,那么您可以通过两种方式处理它

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() );
}

你能注册一个关机功能吗? 即使发生超时,也会调用关闭函数。 有了它,您可以打印或保存您想要的日志文件。 我不确定是否有更好的方法在 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

我不习惯 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('your_email_address@example.com', 'Subject', implode("\r\n", $email_body));
       //or you can save this to some log file
    }
}

看起来 PHP 正在等待一些资源,例如。 文件访问、数据库、邮件服务器(我认为是文件)。

  • 您是否尝试在一个会话中在多个选项卡上使用您的应用程序?
  • 您是否尝试从多台机器登录同一个帐户?
  • 也许脚本的某些部分正在打开文件而不是关闭它?
  • 您是否从打开网站开始跟踪用户操作以获取此错误?
  • 检查您的生产数据库 - 也许连接限制很小?

编辑

我看到您正在使用dannyvankooten/vat.php库,它向外部服务发出一些请求。 这可能是您问题的根源。 该库使用 curl 发出请求。 作者是设置CURLOPT_CONNECTTIMEOUTCURLOPT_TIMEOUT没有设置你的脚本有时会等待更长的时间比它被限制max_execution_time设置。

我认为你现在不应该增加超时。 如果您执行“try catch”,您可能会了解潜在的问题。 如果没有,请检查在特定方法或类中执行的操作/函数。 您可能正在查询一个巨大的表,并且可能试图使用这些信息。

如果你这样做

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

这将指示您为该操作运行了多少查询

没有办法在 try catch 中捕获它,因为它实际上是 PHP 错误而不是异常。

为了能够调试这个,你有几个选择:

  1. 在代码中添加一些日志以识别超时的位置
  2. 您可以使用Laravel 转储服务器包来转储日志。 这实际上将随 Laravel 5.7 一起提供,但您现在可以随时添加该包

我安装了 laravel-debugbar。我认为它对你有帮助。

composer require barryvdh/laravel-debugbar 接下来打开 config/app.php 并在 'providers' 数组中添加:

Barryvdh\Debugbar\ServiceProvider::class,

在别名数组类中:

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

你可以查看

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

// 做点什么… });

您无法捕获 php 超时错误。 当 php 解释器停止执行时会发生此错误。 您只能增加时间限制,例如 ini_set('max_execution_time', 300) 或将长时间执行的工作转换为 cron 作业,例如 laravel 任务计划。

新的哨兵版本将为您提供正确的堆栈跟踪。

您必须使用“getsentry/sentry-php”版本 >=“2.0”

老实说,您最好的方法是安装 xdebug 并以老式的方式对其进行调试,通过整个请求找到瓶颈并尝试找出它来自哪里。 Laravel 以及其他框架都旨在尽可能流畅地运行。 如果您遇到任何此类错误,则意味着您可能只是编写了错误的代码。

如果没有更多信息,也很难为您提供具体建议。 我的建议是重新创建 Laravel 应用程序所面临的环境规范(您可以使用 Docker 或 Vagrant 或任何您想到的可行的方法),然后使用 xdebug 运行以找出问题所在。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM