Redis后端ASGI通道层实现
项目描述
提供使用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
使用BZPOPMIN
、DEL
、EVAL
、EXPIRE
、KEYS
、PIPELINE
、ZADD
、ZCOUNT
、ZPOPMIN
、ZRANGE
、ZREM
、ZREMRANGEBYSCORE
RedisPubSubChannelLayer
使用PUBLISH
、SUBSCRIBE
、UNSUBSCRIBE
本地开发
您可以使用以下命令在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自述文件。
项目详情
下载文件
下载适用于您的平台的文件。如果您不确定该选择哪个,请了解更多关于安装包的信息。