我使用第三方API使用urllib(不知道哪个版本),在一段时间内,呼叫将被阻止,最后一次从服务登录是“重置丢弃连接...”,可以从源代码中找到urllib3中的connectionpool.py:
connnectionpool.py
def _get_conn(self, timeout=None):
"""
Get a connection. Will return a pooled connection if one is available.
If no connections are available and :prop:`.block` is ``False``, then a
fresh connection is returned.
:param timeout:
Seconds to wait before giving up and raising
:class:`urllib3.exceptions.EmptyPoolError` if the pool is empty and
:prop:`.block` is ``True``.
"""
conn = None
try:
conn = self.pool.get(block=self.block, timeout=timeout)
except AttributeError: # self.pool is None
raise ClosedPoolError(self, "Pool is closed.")
except Empty:
if self.block:
raise EmptyPoolError(self,
"Pool reached maximum size and no more "
"connections are allowed.")
pass # Oh well, we'll create a new connection then
# If this is a persistent connection, check if it got disconnected
if conn and is_connection_dropped(conn):
log.info("Resetting dropped connection: %s" % self.host)
conn.close()
if getattr(conn, 'auto_open', 1) == 0:
# This is a proxied connection that has been mutated by
# httplib._tunnel() and cannot be reused (since it would
# attempt to bypass the proxy)
conn = None
return conn or self._new_conn()
然后我检查conn.close,我猜它可能会在关闭函数中被阻止:
def close(self):
"""
Close all pooled connections and disable the pool.
"""
# Disable access to the pool
old_pool, self.pool = self.pool, None
try:
while True:
conn = old_pool.get(block=False)
if conn:
conn.close()
except Empty:
pass # Done.
所以这似乎意味着old_pool除了阻止之外什么都没有。由于old_pool是LifoQueue,而block = False意味着如果没有数据获取则返回,所以这里似乎没问题。
但是,我在一段时间内遇到阻塞(即使频率非常低),我想知道原因可能是什么原因?
感谢您的帮助
===============================
实际上我使用Facebook Ads SDK进行Facebook API调用,这会在阻塞发生之前给出最后一条日志消息:
"logs/aam.log.bk.2015111802:[connectionpool.py:238 - _get_conn Wed, 18 Nov 2015 02:11:21;INFO] Resetting dropped connection: graph.facebook.com"
这就是为什么我猜它与urllib中的conn.close有关,因为Facebook Ads SDK和urllib3中似乎都没有其他块(而另一个奇怪的是Facebook SDK似乎直接使用urllib以外的请求,所以我不喜欢不知道为什么它与urllib有关,如果你知道的话请教我,我只问一个问题给FB支持团队)
从Facebook SDK源代码,它应该与facebookads / api.py中的以下代码相关:
# Get request response and encapsulate it in a FacebookResponse
if method in ('GET', 'DELETE'):
response = self._session.requests.request(
method,
path,
params=params,
headers=headers,
files=files,
)
else:
response = self._session.requests.request(
method,
path,
data=params,
headers=headers,
files=files,
)
fb_response = FacebookResponse(
body=response.text,
headers=response.headers,
http_status=response.status_code,
call={
'method': method,
'path': path,
'params': params,
'headers': headers,
'files': files,
},
)
正如所描述的原始问题,它发生在一个非常低的频率,但它发生在不同的API中,所有这些都在较低级别进行上述调用。
如果需要其他信息,请告诉我,谢谢你的帮助〜