python-3.x - 与 aiohttp 应用程序内的 Redis(aioredis) 失去连接

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

我正在aiohttp中构建基于text/event-stream的 View ,并在aioredis实现中使用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

aiohttp View 订阅 channel 并将其写入 Stream 响应

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)

因此 Sonnection 丢失,这也会导致 concurrent.futures.CancelledError 并且保持事件连接将丢失。 连接经常丢失可以吗?我期待有持久的连接,如果我错过了什么,抱歉。

最佳答案

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

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

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

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

关于python-3.x - 与 aiohttp 应用程序内的 Redis(aioredis) 失去连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39439952/

相关文章:

ruby-on-rails - 在 Rails 中是否有比 Observers 更直接的方式来执行发布/订阅模式?

python - 统一码编码错误 : 'mbcs' codec can't encode characters in position 0--1: invalid character upon running a PyInstaller-compiled script

python - 谷歌驱动器 API : creation of subfolder under root instead of the parent folder ID provided

python-3.x - 在 Docker 容器内运行应用程序单元测试

python - 使用 Ray 并行化大型程序的正确方法

ruby-on-rails - 如何在 redis rails 中订阅多个发布者?

python - 对 Pandas 数据框上的函数进行多重处理

unit-testing - 当连接位于结构中时,我应该如何在 Go 中模拟 Redis 连接?

redis - 如何安装最新版本的redis?

php - 使用 PHP 在 Web 上进行实时更新?