使用 Celery 和 Redis 实现 SSL 连接
首先
Celery是用于在Python中处理队列任务的框架。
虽然Celery可以使用Redis作为Broker,但在使用Azure的Azure Redis Cache时,遇到了使用SSL的问题,因此在这里记录下使用方法。
环境
-
- Python: 3.5.2
-
- Celery: 4.0.0
- Redis: Azure Redis Cache を利用。Standardプランのため、Virtual Network内に配置することができず、Global IPに紐付いたHostに対してアクセスするので、セキュリティのためSSLの利用が必要となる。Premium プランだと、Private Subnet の中に配置することが可能。Premium Azure Redis Cache の Virtual Network のサポートを構成する方法
我們假設使用Flask作為Web應用程序,但我認為在其他環境中也是一樣的。
要使用SSL
根据Celery 4.0(latentcall)的最新消息,从版本4.0开始,Celery可以在Redis中使用SSL连接。
据说可以通过设置broker_use_ssl来使用它,但对于Redis而言,即使盲目配置此信息也无法正常工作。
Error while reading from socket: (104, 'Connection reset by peer')
遇到这个错误会导致困扰。这个错误是由于在Celery内部与Redis的连接中,使用了redis.connection.Connection而不是redis.connection.SSLConnection所导致的。
修复Redis的SSL支持。如果不参考此拉取请求进行配置,则无法使用SSL。
from celery import Celery
from redis.connection import SSLConnection
from .config import broker_use_ssl
def make_celery(app):
celery = Celery(app.import_name, backend=app.config['CELERY_BACKEND'],
broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)
celery.conf.update(broker_use_ssl=broker_use_ssl)
# URL: https://github.com/celery/kombu/pull/634
if celery.conf.broker_use_ssl:
celery.backend.connparams.update(celery.conf.broker_use_ssl) # <- ここ
celery.backend.connparams['connection_class'] = SSLConnection # <- ここ
TaskBase = celery.Task
class ContextTask(TaskBase):
abstract = True
def __call__(self, *args, **kwargs):
with app.app_context():
return TaskBase.__call__(self, *args, **kwargs)
celery.Task = ContextTask
return celery
通过make_celery的参数传递的app是Flask应用程序的上下文。
在设置broker_use_ssl之后,需要设置celery.backend.connparams[‘connection_class’] = SSLConnection。
另外,在文件中指出,可以将broker_use_ssl设置为True或字典,但是即使将其设置为True,它也不起作用。您需要设置一个字典。与Ruby不同的是,如果字典为空,它会被判定为False。
broker_use_ssl = {'ssl_cert_reqs': ssl.CERT_NONE}
我认为留作备用是个好主意。
密码
在中国的当地语言中重新表述以下内容,只需提供一个选项:
在Celery中,设置密码。
CELERY_BROKER_URL = "redis://:password@hostname:port/db_number"
必须以这种形式进行设置。由于我浪费了一些关于HTTP之类的知识,所以我开始怀疑是否可以在URI中包含密码。但是当我查看内部实现时,发现URI会被正确解析。
最后
芹菜的内部实现出乎意料地复杂且难以阅读。
此外,Azure的文档中有关使用Python在Azure Redis Cache中的方法。
由于一些Redis客户端不支持SSL,所以新的Azure Redis Cache实例默认情况下禁用了非SSL端口。在撰写本文时,redis-py客户端不支持SSL。
根据提交日志,redis-py在2014年就已经支持SSL。希望更新旧有的描述,以免造成困扰。
请参考此链接
github – Fix Redis SSL support
What’s new in Celery 4.0 (latentcall)