urllib3连接池-连接池已满,丢弃连接。

64

看到

urllib3.connectionpool WARNING - Connection pool is full, discarding connection
意思是我的数据会因为连接丢失而有效地丢失(由于连接中断)
或者这是否意味着连接已经断开(因为池已满); 但是,当连接池可用时,相同的连接将稍后重新尝试?

https://dev59.com/e2Ml5IYBdhLWcg3wXF9f - Pedro Lobito
2个回答

65

没有数据丢失!

连接在请求完成后被丢弃(因为池已满,如前所述)。这意味着这个特定的连接将来不会被重用。

由于urllib3 PoolManager会重用连接,它会限制每个主机保留多少个连接,以避免积累太多未使用的套接字。当池中没有任何空闲套接字可用时,可以配置PoolManager以避免创建过多的套接字,方法是使用PoolManager(..., block=True)

如果您依赖并发性,增加池的大小(maxsize)至少与您使用的线程数一样大可能是一个好主意,这样每个线程实际上都有自己的连接。

更多详细信息请参阅:https://urllib3.readthedocs.io/en/latest/advanced-usage.html#customizing-pool-behavior


2
根据你提到的文档,那是一个非常错误的答案和解释。没有所谓的“稍后重试”,所有连接都会立即打开,无论池大小如何。此外,如果不更改maxsize(或pool_size,如果使用不同的主机),_增加_线程数将不能消除警告,反而会增加它们! - MestreLion
1
@MestreLion 现在重新阅读,我认为你是对的。我的回答非常令人困惑。我的意思是第一部分是正确的解释(“连接正在被断开”),但第二部分即它正在被重用确实是不正确的。我还意味着他们应该增加池大小,而不是线程数。我澄清了答案,感谢你指出。 - shazow
2
@dvdblk:警告和性能之间没有“平衡”:要想不出现警告,只需将您的maxsize设置为您正在使用的工作线程数即可。这样,所有连接都将保留在池中以供重用,因此不会出现警告。而要提高性能,只需增加您的工作线程。我读到过,在互联网(即慢速)I/O方面,每个CPU核心大约需要4-5个线程是最优的。 - MestreLion
1
@shazow:更新非常好!但是像“它将限制每个主机允许的连接数”这样的陈述仍然不准确:urllib3将始终打开您请求的所有连接,即使在使用后丢弃一些连接。 - MestreLion
1
@dvdblk:在aiohttp中设置工作线程完全超出了这个问题的范围,但你肯定可以做到,只需查看其连接器文档即可。 - MestreLion
显示剩余5条评论

18
根据 自定义池行为文档,你的两种解释都不正确
默认情况下,如果池中没有空闲连接,则会创建一个新连接以响应新请求。但是,如果已有超过maxsize个连接,则不会保存此连接。这意味着maxsize并不决定可以对特定主机打开的最大连接数,而只决定保留在池中的最大连接数。
强调一下,因此连接并不是被中止后稍后重试的。它们是立即根据请求创建的,并返回结果。然后,在完成它们之后,这些“额外”的连接被丢弃,即它们不会保留在池中以供以后重用。
例如,如果您的maxsize为10(使用requests时的默认值为10),并且您同时发起了50个请求,那么这50个连接将立即执行,并在完成后仅有10个连接保留在池中,而其余40个则被丢弃(并引发警告)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接