【问题标题】:Loosing connection with Redis(aioredis) inside aiohttp app在 aiohttp 应用程序中失去与 Redis(aioredis) 的连接
【发布时间】:2016-09-11 19:40:27
【问题描述】:

我正在aiohttp 中构建一个基于text/event-stream 的视图,并在aioredisimplementaion 中使用Redis 的pub-sub。它看起来像:

从服务器获取一些数据并发布到 chanell 的脚本

def main(host, port):
    server_logger.info('Got params connection host {0}, port {1}'.format(host, port))
    loop = asyncio.get_event_loop()
    title = None
    redis = loop.run_until_complete(create_redis(('localhost', 6379)))
    while True:
        new_title = loop.run_until_complete(get_title(host, port))
        if new_title != title:
            loop.run_until_complete(redis.publish('CHANNEL', new_title))
            title = new_title
    loop.close()
    return False

订阅频道并将其写入Stream响应的aiohttp视图

stream = web.StreamResponse()
stream.headers['Content-Type'] = 'text/event-stream'
stream.headers['Cache-Control'] = 'no-cache'
stream.headers['Connection'] = 'keep-alive'

await stream.prepare(request)

redis = await create_redis(('localhost', 6379))
channel = (await redis.subscribe('CHANNEL'))[0]

while await channel.wait_message():
        message = await channel.get()
        if message:
            stream.write(b'event: track_update\r\n')
            stream.write(b'data: ' + message + b'\r\n\r\n')
        else:
            continue

我得到了很多类似的东西:

DEBUG:aioredis:Creating tcp connection to ('localhost', 6379)

因此丢失连接也会导致concurrent.futures.CancelledError 和keep-alive 连接将丢失。 经常丢失连接可以吗?我期待有持久的连接,如果我遗漏了什么,对不起。

【问题讨论】:

    标签: python-3.x redis publish-subscribe aiohttp


    【解决方案1】:

    首先在请求处理程序中创建新的 redis 连接是个坏主意。 请为每个应用程序使用一个连接池。

    您可能会收到https://github.com/KeepSafe/aiohttp/blob/master/demos/polls/aiohttpdemo_polls/main.py 作为推荐设计原则的草图。

    关于保持连接——它们不是很持久,但默认在 75 秒不活动期后关闭。

    您可以通过将keep_alive=300 参数传递给app.make_handler() 调用来增加周期,但设置非常大的值并不可靠——在TCP 自然期间,在某些情况下连接可能会在没有通知的情况下中断。 如果您没有数据要传递,最好保持合理的慢速超时并定期向服务器发送自定义 ping 请求。

    【讨论】:

    • 感谢您的回答。但是如果text/event-stream 连接只是一种方式,那么我将无法从客户端向服务器发送 ping。
    • 在这种情况下,只需将keep_alive timeout 增加到疯狂的值并保持手指交叉
    • 似乎在keep_alive 时间中添加了一些额外的服务器计时。使用值120 我最终得到170 秒超时请求。不管怎样,你的回答让我明白了很多。无法在网上找到任何使用 SSE(处理超时等)的“真实”示例。我现在不确定 SSE 是否适合从服务器以 3-6 分钟的间隔发送数据:(这里的 websocket 是开销,因为我只有一种数据流方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-28
    • 2019-10-22
    • 2014-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多