V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
awanganddong
V2EX  ›  PHP

thinkphp 使用 laravel-queue 组建出现的问题

  •  
  •   awanganddong · 114 天前 · 980 次点击
    这是一个创建于 114 天前的主题,其中的信息可能已经有所发展或是发生改变。
           //laravel 框架队列引入
            $queue = new Queue();
            $container = $queue->getContainer();
            $config = [
                'options' => [
                    'prefix' => 'laravel_database_'
                ],
                'default' => [
                    'host' => \think\facade\Config::get('cache.redis.host', ''),
                    'password' => \think\facade\Config::get('cache.redis.password', ''),
                    'port' => \think\facade\Config::get('cache.redis.port', ''),
                    'database' => 0,
                ],
            ];
            $container->bind("redis", function ($container) use ($config) {
                return new RedisManager($container, 'predis', $config);
            });
            $queue->getContainer()->bind('Illuminate\Contracts\Queue\EntityResolver', function () {
                return new \Illuminate\Database\Eloquent\QueueEntityResolver();
            });
            $queue->addConnection([
                'driver' => 'redis',
                'connection' => 'default',
                'queue' => 'default',
                'retry_after' => 90,
                'block_for' => null,
            ]);
            $queue->setAsGlobal();
            //laravel 框架队列结束
            $data = json_encode(['name' => 'aa']);
            $ret = $queue->push('App\Jobs\TestJobs', $data);
    

    以上操作可以在 tp 把项目推送到 redis 上边,但是出现以下问题。应该是那个服务没有注册

    Illuminate\Contracts\Container\BindingResolutionException: Unresolvable dependency resolving [Parameter #0 [ <required> $data ]] in class App\Jobs\TestJobs in /vendor/laravel/framework/src/Illuminate/Container/Container.php:993
    Stack trace:
    #0 /vendor/laravel/framework/src/Illuminate/Container/Container.php(931): Illuminate\Container\Container->unresolvablePrimitive(Object(ReflectionParameter))
    #1 /vendor/laravel/framework/src/Illuminate/Container/Container.php(872): Illuminate\Container\Container->resolvePrimitive(Object(ReflectionParameter))
    #2 /vendor/laravel/framework/src/Illuminate/Container/Container.php(834): Illuminate\Container\Container->resolveDependencies(Array)
    #3 /vendor/laravel/framework/src/Illuminate/Container/Container.php(681): Illuminate\Container\Container->build('App\\Jobs\\TestJo...')
    #4 /www/walle/bitian_queue/8_989_20210815_104701/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(785): Illuminate\Container\Container->resolve('App\\Jobs\\TestJo...', Array, true)
    #5 /vendor/laravel/framework/src/Illuminate/Container/Container.php(629): Illuminate\Foundation\Application->resolve('App\\Jobs\\TestJo...', Array)
    #6 /vendor/laravel/framework/src/Illuminate/Foundation/Application.php(770): Illuminate\Container\Container->make('App\\Jobs\\TestJo...', Array)
    #7 /vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(215): Illuminate\Foundation\Application->make('App\\Jobs\\TestJo...')
    #8 /vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(88): Illuminate\Queue\Jobs\Job->resolve('App\\Jobs\\TestJo...')
    #9 /vendor/laravel/framework/src/Illuminate/Queue/Worker.php(368): Illuminate\Queue\Jobs\Job->fire()
    #10/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(314): Illuminate\Queue\Worker->process('redis', Object(Illuminate\Queue\Jobs\RedisJob), Object(Illuminate\Queue\WorkerOptions))
    #11 /vendor/laravel/framework/src/Illuminate/Queue/Worker.php(134): Illuminate\Queue\Worker->runJob(Object(Illuminate\Queue\Jobs\RedisJob), 'redis', Object(Illuminate\Queue\WorkerOptions))
    #12 /vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(112): Illuminate\Queue\Worker->daemon('redis', 'high,default', Object(Illuminate\Queue\WorkerOptions))
    #13 /vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(96): Illuminate\Queue\Console\WorkCommand->runWorker('redis', 'high,default')
    #14 /vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\Queue\Console\WorkCommand->handle()
    #15 /vendor/laravel/framework/src/Illuminate/Container/Util.php(37): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
    #16 /vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(93): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
    #17 /vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(37): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
    #18 /vendor/laravel/framework/src/Illuminate/Container/Container.php(590): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
    #19 /vendor/laravel/framework/src/Illuminate/Console/Command.php(134): Illuminate\Container\Container->call(Array)
    #20 /vendor/symfony/console/Command/Command.php(255): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
    #21 /vendor/laravel/framework/src/Illuminate/Console/Command.php(121): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
    #22 /vendor/symfony/console/Application.php(1009): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
    #23 /vendor/symfony/console/Application.php(273): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Queue\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
    #24 /vendor/symfony/console/Application.php(149): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
    #25 /vendor/laravel/framework/src/Illuminate/Console/Application.php(93): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
    #26 /vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(131): Illuminate\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
    #27/artisan(37): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
    #28 {main}
    
    9 条回复    2021-08-15 21:30:09 +08:00
    Rache1
        1
    Rache1  
       114 天前
    tp 的 queue 和 laravel 的 job 不一样,参数是传递给 Job 的 fire 方法的,见 fire 方法的签名,第一个是 job,第二个就是传递的参数。
    awanganddong
        2
    awanganddong  
    OP
       114 天前
    @Rache1 我是在 tp 框架里边引入 laravel 组件,没有走 tp 那一套业务逻辑
    Rache1
        3
    Rache1  
       114 天前
    @awanganddong 看你 TestJobs 的代码
    ajaxfunction
        4
    ajaxfunction  
       114 天前   ❤️ 1
    把两大冤家搅和到一起 组成一个项目。。。 牛
    awanganddong
        5
    awanganddong  
    OP
       114 天前
    @Rache1
    ```
    <?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 Illuminate\Support\Facades\Log;

    class TestJobs implements ShouldQueue
    {
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $data;

    /**
    * Create a new job instance.
    *
    * @return void
    */
    public function __construct($data) //data 如果是在这里的话,就是上图那个问题,这里代码好像是同步执行的
    {

    }

    /**
    * Execute the job.a
    *
    * @return void
    */
    public function handle($data) //如果在这里的话就是 Symfony\Component\Debug\Exception\FatalThrowableError: Call to undefined method App\Jobs\TestJobs::fire()
    {

    var_dump($data);
    Log::error('test jobs');
    }

    }


    ```
    awanganddong
        6
    awanganddong  
    OP
       114 天前
    @ajaxfunction
    现在是拆分成生产者和消费者。
    现在看来是麻烦了,实在不行就直接服务之间调用了。坏处是增加了一层网络调用 。
    Rache1
        7
    Rache1  
       114 天前
    @awanganddong

    看源码,你需要一个 fire 方法,第一个参数接受 Job 对象,第二个接受传递的 payload 。

    即把你的构造函数的 $data 放到 fire 函数的第二个参数上,你可以把 handle 改成 public function fire($job, $data)

    https://github.com/illuminate/queue/blob/master/Jobs/Job.php#L92
    awanganddong
        8
    awanganddong  
    OP
       114 天前
    @Rache1 我如果让 testJob 继承这个类就直接报错,我现在不知道怎么继承该类的方法
    awanganddong
        9
    awanganddong  
    OP
       114 天前
    @Rache1 我明白你的意思了

    ```
    https://www.flynsarmy.com/2014/05/using-illuminatequeue-outside-laravel/

    Queue::push($date, 'EmailTest', array('foo' => 'bar'));

    class EmailTest
    {
    public function fire($job, $data)
    {
    mail('[email protected]', 'hiya', $data['foo']);
    }
    }

    ```
    谢谢你了
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3539 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 01:28 · PVG 09:28 · LAX 17:28 · JFK 20:28
    ♥ Do have faith in what you're doing.