跳转到主要内容

基于Redis的ASGI通道层实现

项目描述

https://api.travis-ci.org/django/asgi_redis.svg https://img.shields.io/pypi/v/asgi_redis.svg

一个使用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_timeoutsocket_timeoutsocket_keepalivesocket_keepalive_options。有关更多信息,请参阅 redis-py 文档

本地和远程模式

还支持“本地和远程”模式,其中Redis通道层与本地机器的通道层(asgi_ipc)结合使用,以便将所有常规通道通过本地层路由,而将所有单读器和进程特定通道通过Redis层路由。

这允许像 http.requestwebsocket.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 (17.4 kB 查看哈希值)

上传时间 源代码

构建分发

asgi_redis-1.4.3-py2.py3-none-any.whl (20.0 kB 查看哈希值)

上传时间 Python 2 Python 3