Heroku 与 Django、Celery 和 CloudAMPQ - 超时错误

Posted

技术标签:

【中文标题】Heroku 与 Django、Celery 和 CloudAMPQ - 超时错误【英文标题】:Heroku with Django, Celery and CloudAMPQ - timeout error 【发布时间】:2020-12-25 15:53:24 【问题描述】:

按照“Django 3 示例”一书的第 7 章,我正在建立一个在线商店。这本书的作者是Antonio Melé。

在我的本地机器上一切正常。当我将它部署到 Heroku 时,它也能正常工作。

但是,当我尝试使用 Celery 和 RabbitMQ(CloudAMQP,Little Lemur,在 Heroku 上)时,工作人员应该发送给客户的电子邮件消息没有发送。该任务需要超过 30 秒,然后崩溃:

heroku[router]: at=error code=H12 desc="Request timeout" method=POST

我创建了一个 tasks.py 文件,用于发送电子邮件。我的 settings.py 文件包含 Celery 的以下行:

broker_url = os.environ.get('CLOUDAMQP_URL')
broker_pool_limit = 1 
broker_heartbeat = None 
broker_connection_timeout = 30 
result_backend = None 
event_queue_expires = 60 
worker_prefetch_multiplier = 1 
worker_concurrency = 50 

这取自https://www.cloudamqp.com/docs/celery.html

而我的Procfile如下,

web: gunicorn shop.wsgi --log-file -
worker: celery worker --app=tasks.app

我错过了什么吗?

谢谢!

【问题讨论】:

我现在将 Procfile 行编辑为:worker: celery -A appname worker -l info。然后 Heroku 尝试发送电子邮件,但它再次崩溃。这一次,它一直在尝试,它给了我以下错误消息:consumer: Cannot connect to amqp://guest:**@127.0.0.1:5672//: [Errno 111] Connection denied .它正在尝试连接到 localhost,即使我在 settings.py 中引用了正确的 Heroku 变量:broker_url = os.environ.get('CLOUDAMQP_URL') 【参考方案1】:

在尝试解决这个问题几天后,我联系了支持部门CLOUDAMQP

他们帮助我找出问题与 Celery 没有正确识别我的 BROKER_URL 有关。

然后我看到了@jainal09 here 的这个好评论。应该在settings.py 中设置一个额外的变量:

CELERY_BROKER_URL = '<broker address given by Heroku config>'

添加额外的行解决了这个问题。现在 Heroku 可以正确发送电子邮件了。

【讨论】:

【参考方案2】:

对 heroku 相当熟悉,虽然不是你的技术栈。所以处理heroku超时的一般方法是这样的:

首先,确定导致超时的确切原因。一件或多件事情要花很多时间。

现在您有 3 个主要选项。

    Heroku 调度程序(或其他几个类似的插件之一)。如果您可以通过终端命令运行某种脚本,并且 10 分钟/1 小时/24 小时检查脚本是否需要运行对您来说足够好,这将非常有用。我通常认为这是最直接的解决方案,但它并不总是可以接受的。根据您发送的电子邮件内容,延迟 5-15 分钟的电子邮件可能是可以接受的。 后台进程工作者。看起来这是您尝试对 Celery 执行的操作,但配置不正确,可能对此无济于事。 优化。 heroku 设置 30 秒超时的原因是因为一般来说,用户等待 30 秒等待响应确实没有充分的理由。我在摸索为什么发送一封电子邮件需要超过 30 秒,除非你需要发送几百个或者电子邮件非常非常大。或者,您可能在发送电子邮件之前做了大量工作,尽管这提出了一个问题,即为什么不将这些工作与发送电子邮件命令分开进行。我怀疑在尝试设置后台进程工作程序之前,您可能应该调查一下原因。

【讨论】:

感谢您分享您的想法。这里有一些 cmets: 1) Heroku Scheduler 听起来是个不错的选择,但它并不能完全从我的设置中解决我的问题; 2) Celery 配置了 RabbitMQ,当我在本地运行时它可以完美运行。电子邮件发送正确; 3) 我完全同意你的看法,它不应该超过 30 秒。 哦,等一下,您说它崩溃并且不发送,这是#3 的变体,解决问题。研究如何为 heroku (devcenter.heroku.com/articles/celery-heroku) 设置 Celary 和 RabitMQ,然后看看你做了什么不同的事情。 Heroku 通常需要与本地不同的设置(我发现它可能会称之为“更严格”)。您可能需要添加一些插件并对您的配置方式进行一些调整。 @MichelMesquita 我正在使用 Heroku 的 CloudAMQP 并且已经正确添加了插件,定义如下:devcenter.heroku.com/articles/cloudamqp>

以上是关于Heroku 与 Django、Celery 和 CloudAMPQ - 超时错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Heroku 上使用 Channels 和 Celery 部署 Django?

Heroku 上的 Celery、RabbitMQ 和 Django:达到内存限制

RabbitMQ 上的 Heroku、Django 和 celery

未执行的任务(Django + Heroku + Celery + RabbitMQ)

如何在heroku服务器中配置django-celery

使用 Heroku 安装 Celery 和 Redis