0

这个问题专门针对 Laravel 6.10 和队列处理。在我的本地机器上,程序运行良好,所有排队的作业都加载良好并处理完成。在我的 GoDaddy 服务器上,当作业尝试加载时,我收到一个神秘错误,内容如下:

/home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Container/Container.php 中的第 805 行引发错误,并带有消息:
    目标类 [] 不存在。

痕迹:
#0 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Container/Container.php(681): Illuminate\Container\Container->build(NULL)
#1 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Container/Container.php(629): Illuminate\Container\Container->resolve(NULL, Array)
#2 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(776): Illuminate\Container\Container->make(NULL, Array)
#3 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(215): Illuminate\Foundation\Application->make(NULL)
#4 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(88): Illuminate\Queue\Jobs\Job->resolve(NULL)
#5 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(354): Illuminate\Queue\Jobs\Job->fire()
#6 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(300): Illuminate\Queue\Worker->process('database', Object(Illuminate\Queue \Jobs\DatabaseJob), 对象(Illuminate\Queue\WorkerOptions))
#7 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(134): Illuminate\Queue\Worker->runJob(Object(Illuminate\Queue\Jobs\DatabaseJob ), '数据库', 对象(Illuminate\Queue\WorkerOptions))
#8 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(112): Illuminate\Queue\Worker->daemon('database', 'default' , 对象(Illuminate\Queue\WorkerOptions))
#9 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(96): Illuminate\Queue\Console\WorkCommand->runWorker('database', '默认')
#10【内部函数】:Illuminate\Queue\Console\WorkCommand->handle()
#11 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(32): call_user_func_array(Array, Array)
#12 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Container/Util.php(36): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#13 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(90): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
#14 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(34): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application),数组,对象(闭包))
#15 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Container/Container.php(590): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application),数组,数组,空)
#16 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Console/Command.php(201): Illuminate\Container\Container->call(Array)
#17 /home/jaredclemence/public_html/theninjaassistant.com/vendor/symfony/console/Command/Command.php(255): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput),对象(照明\控制台\输出样式))
#18 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Console/Command.php(188): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component \Console\Input\ArgvInput), 对象(Illuminate\Console\OutputStyle))
#19 /home/jaredclemence/public_html/theninjaassistant.com/vendor/symfony/console/Application.php(1011): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object( Symfony\Component\Console\Output\ConsoleOutput))
#20 /home/jaredclemence/public_html/theninjaassistant.com/vendor/symfony/console/Application.php(272): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Queue\Console\WorkCommand), Object( Symfony\Component\Console\Input\ArgvInput),对象(Symfony\Component\Console\Output\ConsoleOutput))
#21 /home/jaredclemence/public_html/theninjaassistant.com/vendor/symfony/console/Application.php(148): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput),对象(Symfony\Component\Console\Output\ConsoleOutput))
#22 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Console/Application.php(93): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console \Input\ArgvInput), 对象(Symfony\Component\Console\Output\ConsoleOutput))
#23 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(131): Illuminate\Console\Application->run(Object(Symfony\Component\Console \Input\ArgvInput), 对象(Symfony\Component\Console\Output\ConsoleOutput))
#24 /home/jaredclemence/public_html/theninjaassistant.com/artisan(37): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\输出\控制台输出))
#25 {主要}

我相信问题开始了,并将通过修复第 4 项的跟踪来解决,其中调用了以下内容:Illuminate\Queue\Jobs\Job->resolve(NULL). 我在 GoDaddy 服务器上的两个失败作业中都看到了这一点,但它不会在本地发生。我对 laravel 的了解还不够,无法理解 NULL 值的来源以及如何修复它。这发生在加载作业类之前,但并非对所有排队的作业都发生。只有这个类的工作。

在本地副本和生产副本中,我都使用 GoDaddy 数据库,因此两个系统都与同一个数据库主机通信。我使用名为 CMP_dev 和 CMP_core 的数据库来区分开发表和生产表。因为我使用的是相同的数据库源,所以我可以排除 mysql 设置的更改。

我升级了所有作曲家包并重新测试。然后,我提交了 composer.lock 文件并更新了 GoDaddy 服务器以匹配。因此,我可以排除已经由其他人修复的旧错误代码的问题。

服务器上的PHP版本是7.3.11,本地dev上的PHP版本是7.3.6。好消息是它们都是 7.3.X,这降低了语言变化的风险,但 7.3.6 和 7.3.11 之间仍然可能存在问题,但 GoDaddy 不允许我控制次要版本以外的 PHP 设置数量 7.3。

---- 2020 年 1 月 9 日添加----- 我认为这可能是 Web 服务器的差异。在我的本地机器上,我php artisan serve用来托管软件。在 GoDaddy 上,我使用 Nginx。但是,后来我意识到运行队列的不是服务器。命令行运行队列,两个命令都使用php artisan schedule:run. 这排除了 Web 服务器软件及其所有组件。- - - - - - - - -

我已经成功运行了排队的邮件作业,这意味着队列可以工作。这应该将问题本地化到为我产生问题的两个类。如果我能找到一个问题,我很可能会找到第二个问题,所以我将在此处包含第一个导致问题的工作:

应用程序/工作/ConvertCsvFileToIntermediateFile.php:

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\ContactCsvFile;
use Illuminate\Support\Facades\Log;

class ConvertCsvFileToIntermediateFile implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    public $timeout = 500;

    /** @var ContactCsvFile */
    private $file;
    private $delegate;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(ContactCsvFile $file, $delegate = null)
    {
        $this->file = $file;
        $this->delegate = $delegate;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $this->file->process($this->delegate);
    }

}

在调用 handle() 之前发生错误。我知道这一点,因为当我将 add($this->file)作为句柄的第一行时,永远不会到达该行。

另外,我认为重要的是要注意,当大多数作业失败时,它们的类名会列在 queue:failed 表中。但在这种情况下,queue:failed 表读取时间:“2020-01-08 09:23:23”。

+----+------------+---------+---------- +-----------+  
| 身份证 | 连接 | 队列 | 班级 | 失败于 |  
+----+------------+---------+---------- +-----------+   
| 2 | 数据库 | 默认 | 2020-01-08 09:23:23 | |   
+----+------------+---------+---------- +-----------+   
4

2 回答 2

0

我仍然不知道错误的含义是什么或如何解决它。但是,我找到了解决此问题的方法,我将在此处进行描述,以防其他人解决此问题。

我开始怀疑 queue:failed 表中出现的奇怪的数据库条目表明发生了可怕的事情导致程序在执行过程中失败,这可能导致部分写入数据库。作为一个逻辑解决方案,这对我来说没有意义,因为我的作业在一个应该在失败时回滚的事务中运行。

话虽如此,我查看了潜在的内存膨胀问题和超时问题。我一直遇到超时问题,但是类已经设置为public $timeout = 500;,这应该保证在作业失败前整整 500 秒(这些作业在不到一分钟的时间内失败)。尽管该类允许 500 秒,但 GoDaddy 可以限制进程运行的时间量,因此该进程可能花费了太长时间。

GoDaddy 还可以限制每个进程允许的内存量。由于作业处理大型数据数组,因此可以通过为每个项目创建一个作业而不是创建一个迭代数组的作业来解决时间长度问题和内存膨胀问题。

这就是我解决问题的方法。我确实创建了一个只处理一个项目的工作。我没有将整个数组发送到一个作业,而是迭代数组并将每个项目发送到一个作业。我认为这会增加系统处理每个项目所需的时间,因为程序必须在加载时为每个作业引导应用程序,现在我有数百个作业而不是一个。但是,如果总时间增加,处理单个作业的时间肯定会减少,因为作业只处理了单个项目,然后关闭。进行此更改后,GoDaddy 服务器停止抛出 NULL 错误,并且一切运行良好。

我还惊讶地发现,较小的作业也比使用阵列的单个作业完成得更快。尽管系统必须在每个作业上引导应用程序,但在内存没有过载时系统运行得更快。

于 2020-01-11T21:59:35.297 回答
0

您必须阅读 laravel 6.10 发行说明。某些功能已弃用并已修复。我认为您必须添加 php unit 9 而不是不支持的 v8 并将其添加到 composer required not dev

于 2020-01-08T20:32:39.573 回答