【发布时间】:2019-12-28 20:04:45
【问题描述】:
我正在使用带有 Symfony 4 messenger 组件的 worker。
这个工人是
- 接收消息(来自 rabbitMQ)
- 启动 ffmpeg
- 对视频进行处理
- 并将某些内容保存在数据库中。
为了在 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
然后为了了解可能导致此问题的原因,我尝试调试 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
------------------------------------------------------
一切看起来都还不错吧?
那怎么可能看到这个:
[2019-08-23 10:25:26] messenger.ERROR:重试 App\Api\Message\AMQPvideoFFMPEG - 重试 #1。 {"message":"[object] (App\Api\Message\AMQPvideoFFMPEG: {})","class":"App\Api\Message\AMQPvideoFFMPEG","retryCount":1,"error":"[object ](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(code: 2002): SQLSTATE[HY000] [2002] Connection timed out at /var/www/html/vendor/doctrine/dbal/lib/Doctrine/ DBAL/Driver/PDOConnection.php:31, PDOException(code: 2002): SQLSTATE[HY000] [2002] Connection timed out at /var/www/html/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection .php:27)"} []
我完全迷路了,我错过了什么吗?
这有时会发生,但它在大多数情况下都有效,我想当我的工作人员失去与数据库的连接时会发生此错误,特别是如果 ffmpeg 处理持续 7 分钟或更长时间,但这应该通过 ping 和关闭来避免连接的中间件。所以我不太清楚这里有什么问题。
【问题讨论】:
-
你检查过 MySQL 的日志吗?你的这个中间件并不完美。如果 ffmpeg 的转换时间大于 mysql 的空闲限制,您可能会遇到连接丢失错误。相反,您应该在您的代码中“断开并重新连接”,就在任何 SQL 插入尝试之前(例如,在 Doctrine 的刷新之前)。我个人会选择一个 Doctrine 事件 preFlush/postFlush 事件订阅者:只需断开连接即可。 Doctrine 将在刷新期间重新连接。
-
emix 是个好主意,但现在我不知道如何做到这一点,只对这个处理程序有效
-
这将是一项服务。将其注入处理程序并调用 setter
setEnabled(true)。默认情况下将其设为“禁用”并且不要断开连接。 -
@emix 你能用你的解决方案写一个答案吗?我想试试,但不知道该怎么做。
-
你能告诉我们一些关于上下文的事情吗?小型云数据库,还是成熟的数据库服务器?我问是因为我在云设置中偶然发现了非常有限的允许数据库连接(~10)。
标签: php symfony symfony-messenger