Gre*_*han 5 php symfony symfony-messenger
我正在使用带有 Symfony 4 信使组件的工作人员。
这位工人是
为了在 Symfony 上配置这个工作器,我已经这样做了(中间件很重要):
// 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
Run Code Online (Sandbox Code Playgroud)
然后,为了了解可能导致此问题的原因,我尝试调试信使以查看中间件是否正确配置
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
------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
一切看起来都很好,对吧?
那么怎么可能看到这个:
[2019-08-23 10:25:26] messenger.ERROR:重试 App\Api\Message\AMQPvideoFFMPEG - 重试 #1。{“消息”:“[对象](应用程序\ Api \消息\ AMQPvideoFFMPEG:{})”,“类”:“应用程序\ Api \消息\ AMQPvideoFFMPEG”,“重试计数”:1,“错误”:“[对象] (Doctrine\DBAL\Exception\ConnectionException(代码: 0): 驱动程序中发生异常: SQLSTATE[HY000] [2002] 连接超时 /var/www/html/vendor/doctrine/dbal/lib/Doctrine/DBAL /Driver/AbstractMySQLDriver.php:93,Doctrine\DBAL\Driver\PDOException(代码:2002): SQLSTATE[HY000] [2002] 连接超时 /var/www/html/vendor/doctrine/dbal/lib/Doctrine/ DBAL/Driver/PDOConnection.php:31,PDOException(代码:2002):SQLSTATE[HY000] [2002] 连接超时 /var/www/html/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection .php:27)"} []
我完全迷失了,我错过了什么吗?
有时会发生这种情况,但大多数情况下它都会起作用,我想当我的工作人员失去与数据库的连接时,特别是当 ffmpeg 处理持续 7 分钟或更长时间时,就会发生此错误,但这应该通过 ping 和关闭连接的中间件来避免。所以我不清楚这里的问题是什么。
在阅读了我的中间件的代码,尤其是这个块之后
\n\n\n\nclass DoctrinePingConnectionMiddleware extends AbstractDoctrineMiddleware\n{\n protected function handleForManager(EntityManagerInterface $entityManager, Envelope $envelope, StackInterface $stack): Envelope\n {\n $connection = $entityManager->getConnection();\n if (!$connection->ping()) {\n $connection->close();\n $connection->connect();\n }\n if (!$entityManager->isOpen()) {\n $this->managerRegistry->resetManager($this->entityManagerName);\n }\n return $stack->next()->handle($envelope, $stack);\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n我们可以看到我的处理程序在连接打开后立即被调用。\n我认为这种行为应该有效,但 FFMPEG 可以使用相同的 RabbitMQ\ 消息长时间工作。因此,我的处理程序的最后一步将某些内容插入数据库可能会提供 mySQL 已消失错误或连接超时。
\n\n这就是为什么,我将这段代码片段放入一个方法中,而无需调用处理程序,仅包含与学说连接相关的代码,然后我在向数据库进行任何插入之前调用此方法,如下所示:
\n\npublic function __invoke(AMQPvideoFFMPEG $message)\n {\n // reset connection if not found\n $this->processService->testConnection();\n $process = $this->processService->find($message->getProcess());\n $this->renderServcie->updateQueue($process->getQueue(), "processing");\n\n// some other stuff\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n其中 testConnection() 方法是
\n\n /**\n * Reconnect if connection is aborted for some reason\n */\n public function testConnection()\n {\n $connection = $this->entityManager->getConnection();\n if (!$connection->ping()) {\n $connection->close();\n $connection->connect();\n }\n\n }\n
Run Code Online (Sandbox Code Playgroud)\n\n但在那之后我\xe2\x80\x99ve尝试了另一个问题
\n\n\n\n\n不支持重置非惰性管理器服务。将\n“doctrine.orm.default_entity_manager”服务设置为惰性服务,并在composer.json文件中要求\n“symfony/proxy-manager-bridge”。
\n
安装“symfony/proxy-manager-bridge”后,错误消失了。
\n\n到目前为止,还没有遇到连接超时的情况。等着瞧。
\n