我刚刚从ForkPool切换到gevent,并发(5(作为运行在Kubernetes pod中的Celery工作人员的池方法。切换后,我在工作人员中收到了一个不可恢复的错误:
amqp.exceptions.PreconditionFailed: (0, 0): (406) PRECONDITION_FAILED - delivery acknowledgement on channel 1 timed out. Timeout value used: 1800000 ms. This timeout value can be configured, see consumers doc guide to learn more
broker日志基本上给出相同的消息:
2021-11-01 22:26:17.251 [warning] <0.18574.1> Consumer None4 on channel 1 has timed out waiting for delivery acknowledgement. Timeout used: 1800000 ms. This timeout value can be configured, see consumers doc guide to learn more
我已经设置了CELERY_ACK_LATE
,但不熟悉为确认期设置超时的必要性。在使用流程之前,这种情况从未发生过。任务可能相当长(有时为60-120秒(,但我找不到允许这样做的特定设置。
我在其他论坛的另一篇帖子中看到一位用户将broker配置的超时设置为一个巨大的数字(比如24小时(,但也遇到了同样的问题,这让我觉得可能还有其他问题。
关于如何让员工更有弹性,有什么想法或建议吗?
接受的答案是正确的答案。但是,如果您有一个现有的RabbitMQ服务器正在运行,并且不想重新启动它,您可以通过在RabbitMQ服务器上运行以下命令来动态设置配置值:
rabbitmqctl eval 'application:set_env(rabbit, consumer_timeout, 36000000).'
这将把新的超时设置为10小时(3600000毫秒(。要使其生效,您需要重新启动您的员工。现有的工作进程连接将继续使用旧的超时。
您也可以检查当前配置的超时值:
rabbitmqctl eval 'application:get_env(rabbit, consumer_timeout).'
如果您通过Docker镜像运行RabbitMQ,以下是如何设置值:只需将-e RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS="-rabbit consumer_timeout 36000000"
添加到docker run
,或者将环境RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS
设置为"-rabbit consumer_timeout 36000000"
。
希望这能有所帮助!
为了将来参考,新的RabbitMQ版本(+3.8(似乎为consumer_timeout
引入了严格的默认值(我认为是15分钟(。
我发现的解决方案(不久前也添加到了Celery文档中(是在RabbitMQ中为consumer_timeout
添加一个大数字。
在这个问题中,有人提到将consumer_timeout设置为false,在某种程度上不需要使用大的数字,但显然有一些关于配置格式的细节可以实现。
我在k8s中运行RabbitMQ,刚刚做了一些类似的事情:
rabbitmq.conf: |
consumer_timeout = 31622400000