Django Celery 与 Redis 在 Digital Ocean App Platform 上的问题

Django Celery with Redis Issues on Digital Ocean App Platform

经过大量的反复试验和一步一步的尝试找到解决方案,我想我在这里分享问题并根据我发现的内容自己回答。除了一些零碎的细节外,没有太多关于此的文档,希望这能在将来帮助其他人。

请注意,这特定于 Django、Celery、RedisDigital Ocean App Platform

这主要是关于以下错误和进一步产生的影响:

OSError: [Errno 38] Function not implemented

Cannot connect to redis://......

第一个错误发生在您尝试 运行 芹菜命令时 celery -A your_app worker --beat -l info 或应用平台上的类似内容。看来数字海洋目前不支持此功能。当您犯了一些潜在的错误时,就会出现第二个错误。

第 1 部分:

虽然 Digital Ocean 将来可能会解决这个问题,但这里有一种方法可以提供解决方法。问题是不支持的执行池。 Google“celery execution pools”如果你想了解更多以及它们是如何工作的。默认值为 prefork。但是您需要的是 geventeventlet。为了我的目的,我选择了前者。

无论你选择哪个,你都必须安装它,因为默认情况下它不附带 celery。在我的例子中是:pip install gevent(并且不要忘记将它也添加到您的要求中)。

一旦你有了,你可以重新运行 celery 命令,但请注意 geventbeat 在单个命令中不受支持(将导致错误)。而是执行以下操作:

celery -A your_app worker --pool=gevent -l info 然后分别(如果你想 运行 打败它)在另一个 terminal/console celery -A your_app beat -l info

在第一行中,您还可以像这样指定 concurrency--concurrency=100。这不是必需的,但很有用。阅读它的作用,因为它超出了此处的解决方案。

第 2 部分: 在我的具体情况下,我首先在本地(开发)测试了上述内容以确保它们有效。下一个问题是将其投入生产。我使用 Redis 作为 db/broker.

在我的特定设置中,我的大部分芹菜配置都在 the_main_app/celery/__init__.py 文件中,但有时人们会直接将其放入 the_main_app/celery.py。无论是哪个,请确保 REDIS_URL 设置正确。对于开发,它通常看起来像这样:

YOUR_VAR_NAME = os.environ.get('REDIS_URL', 'redis://localhost:6379') 然后将 YOUR_VAR_NAME 设置为具有以下所有内容的代理:

YOUR_VAR_NAME = os.environ.get('REDIS_URL', 'redis://localhost:6379')
app = Celery('the_main_app')
app.conf.broker_url = YOUR_VAR_NAME

其余设置都记录在“celery first steps with django”帮助页面上,但与我在这里展示的内容无关。

第 3 部分:

当您在应用程序平台上设置 Redis 数据库时(非常简单),您将看到连接详细信息 'public network' 和 'VPC network'。

celery documentation 表示使用以下 URL 格式进行制作:redis://:password@hostname:port/db_number。这没有用。如果您不使用 yaml 文件,那么您只需从 Redis 数据库连接详细信息中复制粘贴整个 连接字符串 (select!),然后设置应用程序- 在名为 REDIS_URL 的 Digital Ocean 项目中设置环境变量并粘贴整个字符串(并对其进行加密!)。

字符串应该看起来像这样(redis with 2 s!) rediss://USER:PASS@URL.db.ondigitialocean.com:PORT.

你快完成了。最后一步是设置工人。我可以 运行 将第 1 部分命令作为 App 平台上的控制台命令来测试它们,但最终我为将它们粘贴到 [=82= 的每一行设置了一个小型工作程序(+ 添加组件) ] 命令。

这基本上就是一步一步的过程。祝你好运!