基于Redis的ASGI通道层实现
项目描述
一个使用Redis作为后端存储的ASGI通道层,支持单服务器和分片配置,以及群组支持。
使用方法
您需要使用至少 hosts 实例化通道层,如果需要其他选项,也可以提供。
示例
channel_layer = RedisChannelLayer(
host="redis",
db=4,
channel_capacity={
"http.request": 200,
"http.response*": 10,
}
)
hosts
要连接的服务器(作为URI或 (host, port) 元组)。默认为 ['localhost', 6379]。传递多个主机以启用分片,但请注意,更改主机列表将丢失一些分片数据。
prefix
添加到所有Redis键的前缀。默认为 asgi:。如果您通过同一Redis实例运行两个或更多完全独立的通道层,请确保它们有不同的前缀。不过,与同一层通信的所有服务器应具有相同的前缀。
expiry
消息过期时间(秒)。默认值为 60。通常情况下您不需要更改此设置,但如果您希望丢弃高峰流量,可以将其降低;如果您希望将高峰流量积压到可以处理时再处理,可以将其提高。
group_expiry
组过期时间(秒)。默认值为 86400。接口服务器将在此时间后断开连接;建议您将其降低以促进系统健康和断开连接。
capacity
默认通道容量。默认值为 100。一旦通道达到容量,将拒绝更多消息。这将对系统不同部分产生不同的影响;例如,HTTP服务器将拒绝连接,而Django发送响应则会等待直到有空间。
channel_capacity
按通道配置的容量。这允许您根据通道名称调整通道容量,并支持通配符和正则表达式。
它应该是一个将通道名称模式映射到所需容量的字典;如果字典键是字符串,则将其解释为通配符,如果是编译后的 re 对象,则将其视为正则表达式。
此示例将 http.request 设置为 200,所有 http.response! 通道设置为 10,所有 websocket.send! 通道设置为 20。
channel_capacity={
"http.request": 200,
"http.response!*": 10,
re.compile(r"^websocket.send\!.+"): 20,
}
如果您想强制执行匹配顺序,请使用 OrderedDict 作为参数;通道将按照字典提供的顺序进行匹配。
symmetric_encryption_keys
传递此参数以启用后端的可选对称加密模式。要使用它,请确保您已安装 cryptography 包,或者在安装 asgi_redis 时指定 cryptography 额外参数。
pip install asgi_redis[cryptography]
symmetric_encryption_keys 应该是一个字符串列表,其中每个字符串都是一个加密密钥。第一个密钥总是用于加密;所有密钥都用于解密,因此您可以在不停机的情况下轮换密钥 - 只需在开头添加一个新密钥,将旧密钥向下移动,然后在消息过期时间过后删除旧密钥。
数据在Redis中既在线上加密,又在线下加密,尽管我们建议您还通过TLS路由Redis连接以提高安全性;Redis协议仍然是未加密的,通道和组键名可能包含对攻击者有用的元数据模式。
密钥 应至少具有 32 字节的熵 - 在用作加密密钥之前,它们将通过SHA256哈希函数进行处理。任何字符串都可以使用,但字符串越短,加密就越容易被破解。
如果您使用Django,您还可以通过 CHANNEL_LAYERS 设置将此设置为您的站点的 SECRET_KEY 设置。
CHANNEL_LAYERS = {
"default": {
"BACKEND": "asgi_redis.RedisChannelLayer",
"ROUTING": "my_project.routing.channel_routing",
"CONFIG": {
"hosts": ["redis://:password@127.0.0.1:6379/0"],
"symmetric_encryption_keys": [SECRET_KEY],
},
},
}
connection_kwargs
传递给 redis-py 连接类的可选额外参数。选项包括 socket_connect_timeout、socket_timeout、socket_keepalive 和 socket_keepalive_options。有关更多信息,请参阅 redis-py 文档。
本地和远程模式
还支持“本地和远程”模式,其中Redis通道层与本地机器的通道层(asgi_ipc)结合使用,以便将所有常规通道通过本地层路由,而将所有单读器和进程特定通道通过Redis层路由。
这允许像 http.request 和 websocket.receive 这样的流量保持在本地层,而无需通过Redis,同时仍然允许群组发送和发送到其他机器上的任意通道正常工作。这将提高性能并减少对您的Redis集群的负载,但 它要求所有常规通道都在同一台机器上消耗。
在实践中,这意味着您必须运行在工作器上,这些工作器消费您应用程序在HTTP或WebSocket终止器同一台机器上处理的所有通道。如果您没有这样做,对该机器的请求将仅被路由到本地队列并挂起,因为没有东西在读取它们。
要使用它,只需在您的配置中使用 asgi_redis.RedisLocalChannelLayer 类代替 RedisChannelLayer,并确保已安装 asgi_ipc 包;无需进行其他更改。
哨兵模式
“哨兵”模式也受支持,其中Redis通道层将连接到Redis哨兵集群,在写入或读取数据之前找到当前的Redis主节点。
哨兵模式支持分片,但不支持多个哨兵集群。要跨多个Redis集群运行键的分片,请使用单个哨兵集群,但让该哨兵集群监控多个“服务”。然后在RedisSentinelChannelLayer的配置中添加服务名称列表。您还可以留空服务列表,该层将拉取哨兵主上配置的所有服务。
Redis哨兵模式不支持URL风格的连接字符串,只支持基于元组的。
哨兵模式的配置如下
CHANNEL_LAYERS = {
"default": {
"BACKEND": "asgi_redis.RedisSentinelChannelLayer",
"CONFIG": {
"hosts": [("10.0.0.1", 26739), ("10.0.0.2", 26379), ("10.0.0.3", 26379)],
"services": ["shard1", "shard2", "shard3"],
},
},
}
“shard1”、“shard2”等条目对应于您在redis sentinel.conf 文件中配置的服务名称。例如,如果您的 sentinel.conf 中说 sentinel monitor local 127.0.0.1 6379 1,那么您想在 RedisSentinelChannelLayer 配置中包括“local”作为服务。
您还可以在 CONFIG 中传递 sentinel_refresh_interval 值,这将启用缓存Sentinel结果指定秒数。这建议减少每次查询哨兵的需求;即使5秒的低值也将显着减少开销。
依赖关系
asgi_redis需要Redis >= 2.6。它支持Python 2.7、3.4、3.5和3.6。
贡献
请参阅主要Channels贡献文档。它还包含有关如何设置开发环境和运行测试的建议。
维护和安全
要报告安全问题,请联系security@djangoproject.com。有关GPG签名和更多信息,请参阅https://docs.django.ac.cn/en/dev/internals/security/。
要报告错误或请求新功能,请打开一个新的GitHub问题。
此存储库是Channels项目的一部分。对于牧羊人和维护团队,请参阅主要Channels自述文件。
项目详情
下载文件
下载适用于您的平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。
源代码分发
构建分发
asgi_redis-1.4.3.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | f1f7a86439d764a6cd6c11d165a500d7287d5447ac8eb4c7b2483456cf3cb383 |
|
MD5 | 19f251b8c656d61109be579ea1f0724a |
|
BLAKE2b-256 | 6b4c43d48dbf54dc64cf0a2866b892dc0215d5cef8a63f2f4d7c55960d654340 |
asgi_redis-1.4.3-py2.py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | ad724d382617b34c2cae08a8c43eb9999f7e695c11e9c534d28b7db0042b898e |
|
MD5 | 0a207e2a6a4256a7b3873b7e02ca15c4 |
|
BLAKE2b-256 | 63c04a2d24cbc0d163ae02bb21eaa1d95311e3948a4fd532e2d6416a02e16471 |