跳转到主要内容

Redis后端ASGI通道层实现

项目描述

https://github.com/django/channels_redis/workflows/Tests/badge.svg https://img.shields.io/pypi/v/channels_redis.svg

提供使用Redis作为后端存储的Django Channels通道层。

有两种可用的实现

  • RedisChannelLayer 是原始层,并自行实现通道和组处理。

  • RedisPubSubChannelLayer 是较新的实现,利用Redis Pub/Sub进行消息分发。此层目前处于 Beta 状态,这意味着在成熟过程中可能会发生破坏性更改。

这两个层都支持单服务器和分片配置。

channels_redis 已在Python 3.8到3.12、redis-py版本4.6、5.0以及开发分支,以及Channels版本3、4和开发分支上进行测试。

安装

pip install channels-redis

注意: 此包的先前版本称为 asgi_redis,如果您需要用于Channels 1.x项目,则该名称在PyPI上仍然可用。此包仅适用于Channels 2项目。

用法

在Django配置文件中设置通道层,如下所示:

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [("localhost", 6379)],
        },
    },
}

或者,您可以使用使用Redis Pub/Sub的替代实现。

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.pubsub.RedisPubSubChannelLayer",
        "CONFIG": {
            "hosts": [("localhost", 6379)],
        },
    },
}

以下列出了CONFIG的可能选项。

主机

要连接的服务器(作为URI、(host, port)元组或符合redis连接的字典)。默认为redis://localhost:6379。传递多个主机以启用分片,但请注意,更改主机列表将丢失一些分片数据。

自签名的SSL连接(例如:Heroku)

"default": {
    "BACKEND": "channels_redis.pubsub.RedisPubSubChannelLayer",
    "CONFIG": {
        "hosts":[{
            "address": "rediss://user@host:port",  # "REDIS_TLS_URL"
            "ssl_cert_reqs": None,
        }]
    }
}

需要符合以下格式的字典来创建Sentinel连接:

{
    "sentinels": [
        ("localhost", 26379),
    ],
    "master_name": SENTINEL_MASTER_SET,
    **kwargs
}

注意额外的master_name键指定了Sentinel主集和任何其他连接kwargs也可以传递。如果进行分片,则可以混合使用纯Redis和Sentinel连接。

如果您的服务器正在监听UNIX域套接字,您也可以使用它来连接:["unix:///path/to/redis.sock"]。这应该比回环TCP连接略快。

前缀

添加到所有Redis键的前缀。默认为asgi。如果您通过同一个Redis实例运行两个或更多完全独立的通道层,请确保它们有不同的前缀。所有与同一层通信的服务器应该有相同的前缀。

过期时间

消息过期时间(秒)。默认为60。您通常不需要更改此设置,但如果您希望丢弃高峰流量或希望在达到它之前将流量回压,则可能需要降低该值。

组过期时间

组过期时间(秒)。默认为86400。在经过这段时间后,通道将从组中删除;建议您降低此值以使系统更健康,并鼓励断开连接。此值不应低于接口服务器中相关的超时值(例如,daphne的--websocket_timeout)。

容量

默认通道容量。默认为100。一旦通道达到容量,它将拒绝更多消息。这将对系统的不同部分产生不同的影响;例如,HTTP服务器将拒绝连接,而Django发送响应将等待直到有空间。

通道容量

按通道配置的容量。这允许您根据通道名称调整通道容量,并支持通配符和正则表达式。

它应该是一个将通道名称模式映射到所需容量的字典;如果字典键是字符串,则将其解释为通配符,如果它是编译后的re对象,则将其视为正则表达式。

此示例将http.request设置为200,所有http.response!通道设置为10,以及所有websocket.send!通道设置为20。

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [("localhost", 6379)],
            "channel_capacity": {
                "http.request": 200,
                "http.response!*": 10,
                re.compile(r"^websocket.send\!.+"): 20,
            },
        },
    },
}

如果您想强制执行匹配顺序,请使用OrderedDict作为参数;然后通道将按照字典提供的顺序进行匹配。

对称加密密钥

传递此参数以启用后端可选的对称加密模式。要使用它,请确保您已安装cryptography包,或在安装channels-redis时指定cryptography额外参数。

pip install channels-redis[cryptography]

对称加密密钥应该是字符串列表,每个字符串都是一个加密密钥。第一个密钥始终用于加密;所有密钥都用于解密,因此您可以无停机地旋转密钥 - 只需在开头添加一个新的密钥,然后将旧的密钥向下移动,然后在消息过期时间过后删除旧的密钥。

数据在Redis中被加密,无论是通过网络传输还是静态存储,但我们建议您也通过TLS路由Redis连接以获得更高的安全性;Redis协议仍然未加密,通道和组密钥名称可能包含可能对攻击者有用的元数据模式。

密钥应至少有32字节熵 - 在用作加密密钥之前,它们将通过SHA256哈希函数进行处理。任何字符串都可以工作,但字符串越短,加密就越容易被破解。

如果您使用Django,您还可以通过CHANNEL_LAYERS设置将其设置为您的站点SECRET_KEY设置。

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": ["redis://:password@127.0.0.1:6379/0"],
            "symmetric_encryption_keys": [SECRET_KEY],
        },
    },
}

on_disconnect / on_reconnect

维护到Redis的长期连接的PubSub层在网络分区事件发生时可能会丢失消息。为了处理这种情况,PubSub层接受可选参数,这些参数将通知Redis断开/重新连接事件消费者。一个常见的用例是确保消费者执行完整的状态重新同步,以确保没有错过任何消息。

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.pubsub.RedisPubSubChannelLayer",
        "CONFIG": {
            "hosts": [...],
            "on_disconnect": "redis.disconnect",
        },
    },
}

然后,在您的通道消费者中,您可以实现处理器

async def redis_disconnect(self, *args):
    # Handle disconnect

依赖关系

要求Redis服务器版本为5.0或更高以使用channels-redis。需要Python 3.8或更高版本。

使用命令

您的Redis服务器必须支持以下命令

  • RedisChannelLayer使用BZPOPMINDELEVALEXPIREKEYSPIPELINEZADDZCOUNTZPOPMINZRANGEZREMZREMRANGEBYSCORE

  • RedisPubSubChannelLayer使用PUBLISHSUBSCRIBEUNSUBSCRIBE

本地开发

您可以使用以下命令在Docker中运行必要的Redis实例

$ docker network create redis-network
$ docker run --rm \
    --network=redis-network \
    --name=redis-server \
    -p 6379:6379 \
    redis
$ docker run --rm \
    --network redis-network \
    --name redis-sentinel \
    -e REDIS_MASTER_HOST=redis-server \
    -e REDIS_MASTER_SET=sentinel \
    -e REDIS_SENTINEL_QUORUM=1 \
    -p 26379:26379 \
    bitnami/redis-sentinel

贡献

请参阅主要的Channels贡献文档。这还包含有关如何设置开发环境和运行测试的建议。

维护和安全

要报告安全问题,请联系security@djangoproject.com。有关GPG签名和更多安全流程信息,请参阅https://docs.django.ac.cn/en/dev/internals/security/

要报告错误或请求新功能,请创建一个新的GitHub问题。

此存储库是Channels项目的一部分。对于牧羊和维护团队,请参阅主要的Channels自述文件

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定该选择哪个,请了解更多关于安装包的信息。

源代码分发

channels_redis-4.2.0.tar.gz (20.8 kB 查看哈希值)

上传时间 源代码

构建分发

channels_redis-4.2.0-py3-none-any.whl (18.4 kB 查看哈希值)

上传时间 Python 3

由以下支持