繁体   English   中英

SSL 传输上的 Asyncio 致命错误 - IndexError Deque Index Out Of Range

[英]Asyncio Fatal Error on SSL Transport - IndexError Deque Index Out Of Range

我一直遇到以下错误,无法解决如何修复它,或者它是否是我需要报告的asyncio中的错误。 我的程序工作正常,它与文档中的示例基本相同,但是当更新数量较少时,它可以向多个客户端发送高达每秒 20 条的消息,但当写入次数增加时,我遇到了这个错误。

我正在使用来自 asyncio 的create_server来让服务器监听新客户端,我相信这会在每个连接上创建一个新连接。 并非所有客户端都停止,只有一个客户端停止,其余客户端继续运行,通常是最后一个连接的客户端,但并非总是如此。 我玩过asyncio/sslproto.py文件,删除了对[0]的引用并用popleft替换它们,这让我得到了不太有用的SSL: BAD_LENGTH错误,我以前遇到过并且使用 asyncio 应该是修复。

当我记录self._write_backlog的值时,它按预期返回了双端队列,并且在错误之前明显有数据,我相信self._write_backlog[0]应该返回双端队列中似乎有一个的最左边的元素。

Fatal error on SSL transport
protocol: <asyncio.sslproto.SSLProtocol object at 0x7f267462e780>
transport: <_SelectorSocketTransport fd=38 read=polling write=<idle, bufsize=0>>
Traceback (most recent call last):
    File "/usr/local/lib/python3.7/asyncio/sslproto.py", line 689, in 
    _process_write_backlog
  del self._write_backlog[0]
IndexError: deque index out of range

在进一步调查中,同样的错误似乎也发生在代码的不同点,但它是同样的错误,就像它试图访问一个空的双端队列一样。

Fatal error on SSL transport
protocol: <asyncio.sslproto.SSLProtocol object at 0x7f45f802ec88>
transport: <_SelectorSocketTransport fd=29 read=polling write=<idle, bufsize=0>>
Traceback (most recent call last):
    File "/usr/local/lib/python3.7/asyncio/sslproto.py", line 664, in _process_write_backlog
    data, offset = self._write_backlog[0]
IndexError: deque index out of range

编辑

我正在运行的 python 版本是 3.7.1,但我也尝试过 3.7.3,它给出了同样的错误。

更新

相信这个问题是由 asyncio 和 OpenSSL https://bugs.python.org/issue37226之间的不兼容引起的

更新 2

GitHub 上提供了一个最小示例

这里的问题与系统资源有关,当您连接大量客户端时,它可能导致 CPU 或内存耗尽,然后在写入失败时导致此错误。

解决方案是实施流量控制以限制一次发送的数据量并防止资源耗尽以下文章有一个很好的简单流量控制示例,即在删除旧数据时阻塞,然后使用高水位线和低水位线恢复. 当数据超过高水位线时,它会触发 pause_writing,然后当数据大小减小到低于低水位线时,写入恢复,这可能会导致明显的减速,具体取决于负载。

作为将您自己的流控制添加到协议的替代方案,asyncio Streams 原语提供了一种简单的方法来写入和读取默认情况下包含流控制的数据,但对我而言,实现起来更加困难,因此我选择在协议级别包含我自己的,如图所示在链接的文章中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM