urllib调用似乎在连接池中以非常低的频率阻塞

时间:2015-11-17 11:11:02

标签: python urllib3

我使用第三方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中,所有这些都在较低级别进行上述调用。

如果需要其他信息,请告诉我,谢谢你的帮助〜

0 个答案:

没有答案