Digital Ocean 应用平台上的 Django Celery 和 Redis 问题

seb*_*ire 7 django redis celery celerybeat digital-ocean

经过相当多的尝试和错误并一步步尝试找到解决方案后,我想我在这里分享问题并根据我发现的内容自己回答它们。除了一些零碎的内容之外,没有太多关于此的文档,这希望将来能对其他人有所帮助。

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

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

OSError:[Errno 38]功能未实现

无法连接到redis://......

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

seb*_*ire 12

第1部分:

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

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

完成后,您可以重新运行 celery 命令,但请注意,单个命令不支持gevent和(将导致错误)。beat相反,请执行以下操作:

celery -A your_app worker --pool=gevent -l info 然后在另一个终端/控制台中单独(如果你想运行beat) celery -A your_app beat -l info

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

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

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

YOUR_VAR_NAME = os.environ.get('REDIS_URL', 'redis://localhost:6379')然后将whereYOUR_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
Run Code Online (Sandbox Code Playgroud)

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

第 3 部分:

当您在应用程序平台上设置 Redis 数据库时(非常简单),您将看到连接详细信息为“公共网络”和“VPC 网络”。

celery文档说要使用以下 URL 格式进行生产:redis://:password@hostname:port/db_number。这不起作用。如果您没有使用 yaml 文件,那么您只需从 Redis DB 连接详细信息中复制粘贴整个连接字符串(从下拉列表中选择!),然后在名为的 Digital Ocean 项目中设置一个应用程序级环境变量REDIS_URL并粘贴到该变量中整个字符串(并且还对其进行加密!)。

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

你快完成了。最后一步是设置工作人员。对我来说,在应用程序平台上将第 1 部分命令作为控制台命令运行来测试它们很好,但最终我为将它们粘贴到运行命令中的每一行设置了一个小型工作程序(+ 添加组件)。

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