Symfony 4 工作者使用学说无法正常工作:SQLSTATE[HY000] [2002]

我正在使用带有 Symfony 4 信使组件的工人。

这个工人是

  • 接收消息(来自rabbitMQ)

  • 启动 ffmpeg

  • 对视频进行处理

  • 并将某些内容保存在数据库中。

为了在 Symfony 上配置这个 worker,我已经这样做了(中间件很重要):

// config/packages/framework.yaml

framework:

    messenger:

        buses:

            command_bus:

                middleware:

                    # each time a message is handled, the Doctrine connection

                    # is "pinged" and reconnected if it's closed. Useful

                    # if your workers run for a long time and the database

                    # connection is sometimes lost

                    - doctrine_ping_connection


                    # After handling, the Doctrine connection is closed,

                    # which can free up database connections in a worker,

                    # instead of keeping them open forever

                    - doctrine_close_connection


        transports:

            ffmpeg:

              dsn: '%env(CLOUDAMQP_URL)%'

              options:

                auto_setup: false

                exchange:

                    name: amq.topic

                    type: topic

                queues:

                  ffmpeg: ~


        routing:

            # Route your messages to the transports, for now all are AMQP messages

            'App\Api\Message\AMQPvideoFFMPEG': ffmpeg

        ## Handle multiple buses ? https://symfony.com/doc/current/messenger/multiple_buses.html

        ## When queries and command should be distinguished

然后为了了解可能导致此问题的原因,我尝试调试 Messenger 以查看中间件是否已正确配置


root@b9eec429cb54:/var/www/html# php bin/console debug:messenger


Messenger

=========


command_bus

-----------


 The following messages can be dispatched:


 ------------------------------------------------------ 

  App\Api\Message\AMQPvideoFFMPEG                       

      handled by App\Api\Message\Handler\FFMPEGHandler  

 ------------------------------------------------------ 


看起来一切正常吧?


沧海一幻觉
浏览 161回答 2
2回答

精慕HU

只需在任何插入操作之前断开连接:public function handle(…){    // your time-consuming business logic    // disconnect if needed    if (!$this->entityManager->getConnection()->ping()) {        $this->entityManager->getConnection()->close();    }    // save your work    $this->entityManager->flush();}

阿晨1998

在阅读了我的中间件的代码后,尤其是这个块https://github.com/symfony/symfony/blob/4.4/src/Symfony/Bridge/Doctrine/Messenger/DoctrinePingConnectionMiddleware.phpclass DoctrinePingConnectionMiddleware extends AbstractDoctrineMiddleware{    protected function handleForManager(EntityManagerInterface $entityManager, Envelope $envelope, StackInterface $stack): Envelope    {        $connection = $entityManager->getConnection();        if (!$connection->ping()) {            $connection->close();            $connection->connect();        }        if (!$entityManager->isOpen()) {            $this->managerRegistry->resetManager($this->entityManagerName);        }        return $stack->next()->handle($envelope, $stack);    }}我们可以看到我的处理程序在连接打开后立即被调用。这种行为应该可以工作,我认为是这样,但是 FFMPEG 可以在很长一段时间内使用相同的 RabbitMQ 消息工作。因此,将某些内容插入数据库的处理程序的最后一步可能会提供 mySQL 已消失错误或连接超时。这就是为什么,我把这个片段放到一个方法中,没有调用处理程序,只包含与学说连接相关的代码,然后我在任何插入到我的数据库之前调用它,如下所示:public function __invoke(AMQPvideoFFMPEG $message)    {        // reset connection if not found        $this->processService->testConnection();        $process = $this->processService->find($message->getProcess());        $this->renderServcie->updateQueue($process->getQueue(), "processing");// some other stuff}testConnection() 方法在哪里 /**     * Reconnect if connection is aborted for some reason     */    public function testConnection()    {        $connection = $this->entityManager->getConnection();        if (!$connection->ping()) {            $connection->close();            $connection->connect();        }    }但在那之后我又尝试了另一个问题不支持重置非惰性管理器服务。将“doctrine.orm.default_entity_manager”服务设置为惰性服务,并在您的 composer.json 文件中要求“symfony/proxy-manager-bridge”。安装“symfony/proxy-manager-bridge”后,错误消失了。到目前为止,还没有遇到连接超时。等着瞧。
打开App,查看更多内容
随时随地看视频慕课网APP