首页 > 解决方案 > python3 HTTP请求需要很长时间

问题描述

我正在使用 requests 库来获取一个简单的 URL(我在这里放了一个虚拟 URL,代码中使用了一个普通的 URL):

import requests
response = requests.get("http://example.com/foo/bar/", headers={"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"})

在本地它工作正常,但是当我将相同的代码放在我的服务器上时,这个请求需要永远完成。我已经为所有这些记录器启用了日志输出:

urllib3.util.retry
urllib3.util
urllib3
urllib3.connection
urllib3.response
urllib3.connectionpool
urllib3.poolmanager
requests

这是他们产生的唯一输出:

2018-05-31 19:55:56,894 - urllib3.connectionpool - DEBUG - Starting new HTTP connection (1): example.com
2018-05-31 19:58:06,676 - urllib3.connectionpool - DEBUG - http://example.com:80 "GET /foo/bar/ HTTP/1.1" 200 None

有趣的是,请求完成总是需要 2 分 10 秒(如果你忽略毫秒)。在本地,它是即时的。

有什么线索我应该下一步看吗?

标签: pythonpython-3.xpython-requestsurllib3

解决方案


这听起来像是底层 IPv6 连接存在问题。请求恰好需要 2 分 10 秒的事实是一个放弃,因为这表明 IPv6 请求超时。

通过使用验证,例如,wgetcurl

wget --inet6-only https://www.example.com -O - > /dev/null
# or
curl --ipv6 -v https://www.example.com

在这两种情况下,我们都会强制该工具通过 IPv6 连接以隔离问题。如果超时,请再次尝试强制 IPv4:

wget --inet4-only https://www.example.com -O - > /dev/null
# or
curl --ipv4 -v https://www.example.com

如果这工作正常,你已经找到了你的问题!但是你问怎么解决?

  1. 蛮力解决方案是完全禁用 IPv6
  2. 您也可以仅为当前会话禁用 IPv6 。
  3. 您可能只想强制请求使用 IPv4。(在链接的答案中,您必须调整代码以始终返回socket.AF_INETIPv4。)
  4. 如果你想为 SSH 解决这个问题,这里是如何为 SSH 强制 IPv4。(简而言之,添加AddressFamily inet到您的 SSH 配置中。)
  5. 您可能还想检查问题是否出在您的DNS 或 TCP上。

没有解决你的问题?

如果那不能解决您的问题,我在这里收集了一些其他可能的解决方案。


推荐阅读