使用Django + Celery时,使用带有SSL的Redis作为代理

这篇文章是Django Advent Calendar 2017和しむどん Advent Calendar 2017第一天的文章。

这里将介绍使用带有SSL的Redis作为Celery的代理以及Django + Celery的配置示例。

总结一下

    • Celeryのデフォルトの設定ではCeleryでブローカーにSSL有りのRedisを使えません。

 

    • SSL有りのRedisを使うには次の設定が必要です。

BROKER_USE_SSL: ブローカーとの接続とSSL設定のSSL使用を切り替えます。 例: {‘ssl_cert_reqs’: ‘none’}

CELERY_REDIS_BACKEND_USE_SSL: Redisがブローカーの場合はこの設定も必要です。例: {‘ssl_cert_reqs’: ssl.CERT_CERT_REQUIRED (sslは標準ライブラリのssl)

Django + Celeryの設定例を https://github.com/TakesxiSximada/TIL/master/django/django-celery-redis-ssl に示しました。

背景 – Background

如果在Azure Redis Cache使用标准方案,则需要分配全局IP才能访问。需要进行密码设置等操作才能使用,同时还需要启用SSL。将带有SSL的Redis指定为Celery的代理商时,使用Celery的默认配置会在与代理商连接时出错。虽然Celery的文档中当然有描述,但Celery的配置项非常多,很难理解。而且解释本身就是对功能的说明,所以很难理解如何使用。因此,在本文中,我们假设在场景中使用Django + Celery的组合,并根据示例代码进行解释。在其中,我们将解释如何将带有SSL的Redis指定为Celery的代理商。

环境

対象バージョンOSmacOS 10.12.4PythonPython3.6.2依存ライブラリrequirementsを参照

要求

为了执行,我使用了以下的库。这些库是明确使用的。

celery
custom_settings
django
ipdb
redis

以下是包含实际安装的依赖库的列表。

#
# This file is autogenerated by pip-compile
# To update, run:
#
#    pip-compile --output-file requirements.txt requirements.in
#
amqp==2.2.2               # via kombu
appnope==0.1.0            # via ipython
billiard==3.5.0.3         # via celery
celery==4.1.0
custom-settings==1.0.post1
decorator==4.1.2          # via ipython, traitlets
django==1.11.6
ipdb==0.10.3
ipython-genutils==0.2.0   # via traitlets
ipython==6.2.1            # via ipdb
jedi==0.11.0              # via ipython
kombu==4.1.0              # via celery
parso==0.1.0              # via jedi
pexpect==4.2.1            # via ipython
pickleshare==0.7.4        # via ipython
prompt-toolkit==1.0.15    # via ipython
ptyprocess==0.5.2         # via pexpect
pygments==2.2.0           # via ipython
pytz==2017.2              # via celery, django
redis==2.10.6
simplegeneric==0.8.1      # via ipython
six==1.11.0               # via custom-settings, prompt-toolkit, traitlets
traitlets==4.3.2          # via ipython
vine==1.1.4               # via amqp
wcwidth==0.1.7            # via prompt-toolkit
zope.dottedname==4.2      # via custom-settings

创建Django项目

我会创建一个Django项目。项目的名称将设为proj。

django-admin startproject proj .

celeryconfig.py 的中文翻译为:芹菜配置.py

在 celeryconfig.py 文件中,我们记录了 Celery 的配置。首先,我们指定了代理人、用于保存返回值的后端以及用于数据传递的格式。如果使用 Celery,这些是必需的设置。在这里使用的 custom_settings 是用于配置的辅助库。更多详细信息请参考 https://pypi.python.org/pypi/custom_settings。

import custom_settings

custom = custom_settings.load('settings_custom')
BROKER_URL = custom.get('BROKER_URL', default='redis://:REDIS_PASS@localhost:6379/0')
CELERY_RESULT_BACKEND = custom.get('BROKER_URL', default='redis://:REDIS_PASS@localhost:6379/0')
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

接下来是配置SSL连接。我们要设置BROKER_USE_SSL和CELERY_REDIS_BACKEND_USE_SSL。

import ssl

BROKER_USE_SSL = {'ssl_cert_reqs': 'none'}
CELERY_REDIS_BACKEND_USE_SSL = {'ssl_cert_reqs': ssl.CERT_REQUIRED}

整体情况如下。

# <CELERY-BASE>
import custom_settings

custom = custom_settings.load('settings_custom')
BROKER_URL = custom.get('BROKER_URL', default='redis://:REDIS_PASS@localhost:6379/0')
CELERY_RESULT_BACKEND = custom.get('BROKER_URL', default='redis://:REDIS_PASS@localhost:6379/0')
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
# </CELERY-BASE>


# <CELERY-SSL>
import ssl

BROKER_USE_SSL = {'ssl_cert_reqs': 'none'}
CELERY_REDIS_BACKEND_USE_SSL = {'ssl_cert_reqs': ssl.CERT_REQUIRED}
# </CELERY-SSL>

准备芹菜。

我们将在之前创建的proj项目中使用Celery。首先,我们要创建proj/celery_.py文件,并按照以下内容填写。

from __future__ import absolute_import

import os

from celery import Celery
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings')


# <CELERY-APP>
app = Celery('proj')
app.config_from_object('celeryconfig')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
# </CELERY-APP>


# <CELERY-TASK>
@app.task
def debug():
    print('OK')
# </CELERY-TASK>

创建和配置Celery对象。

app = Celery('proj')
app.config_from_object('celeryconfig')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

使用 app.config_from_object(‘celeryconfig’) 将读取配置。本次将在 celeryconfig.py 文件中描述 Celery 的配置。对于 Django,也可以在 proj/settings.py 中进行类似的配置,并将 app.config_from_obj(‘celeryconfig’) 的第一个参数设置为 ‘django.conf:settings’,效果是一样的。

我会定义一个任务以进行验证。稍后我会使用 celery call 命令调用这个任务。

@app.task
def debug():
    print('OK')

请确认行动。

创建执行环境。在这里我们省略了venv等,请根据需要适应创建。安装依赖库。

pip install -r requirements.txt

サンプルコードはDjangoプロジェクトなのでマイグレーションを実行します。

python manage.py migrate

Celeryワーカーを起動します。ワーカー起動は -D を付けているのでバックグラウンドで実行します。 –logfile で指定したファイルにログを出力します。

celery -A proj.celery_app worker -D --pidfile .worker.pid --logfile worker.log

我已经准备好了。我已经将proj.celery_.debug实现为一个用于调试的任务。现在将执行该任务。

celery -A proj.celery_app call proj.celery_.debug

以下是显示的哈希值。这表示任务已被注册到Redis并且工作程序的处理已完成。

$ celery -A proj.celery_app call proj.celery_.debug
b77a6165-4458-4540-a3a7-0824f4d6ca30

如果哈希值未显示,那么可能存在错误的部分。请特别检查以下项目。

    • Redisは起動しているか?

 

    • Redisへの接続情報は間違っていないか?

 

    設定ファイルの記述は正しいか?

整理收拾

由于工作进程仍在运行状态,将停止它。工作进程在启动时使用–pidfile选项指定了一个文件来输出进程ID。您可以使用kill命令来关闭该进程。

kill `cat .worker.pid`

请提供一份参考。

    • http://docs.celeryproject.org/en/latest/userguide/configuration.html

 

    https://qiita.com/kawasin73/items/76a22712817ff2a23777
广告
将在 10 秒后关闭
bannerAds