【问题标题】:Node request for certain site results in ETIMEDOUT error most of the time大多数情况下,对某些站点的节点请求会导致 ETIMEDOUT 错误
【发布时间】:2016-07-21 08:36:48
【问题描述】:

规格

以下是我正在运行的系统的一些背景信息:

  • Ubuntu v 14.04

  • 节点 v4.4.0

  • 节点request模块v2.69.0

所有这些都在位于纽约的中心的 DigitalOcean 液滴/服务器上。

 

问题描述

所以我运行下面的js文件:

var request = require('request');

var url = 'http://www.supremenewyork.com/';

request(url, function(err, res, body) { 
  if (err) {
    console.log(err);
    return;
  }

  console.log('body:', body);
});

在我的液滴上。 大约 70-80% 的时间我会尝试这个, 现在每次我尝试这个时,我都会收到类似这样的 ETIMEDOUT 错误:

{ [Error: connect ETIMEDOUT 52.6.25.180:80]
  code: 'ETIMEDOUT',
  errno: 'ETIMEDOUT',
  syscall: 'connect',
  address: '52.6.25.180',
  port: 80 }

值得注意的是,错误似乎是“一波又一波”。也就是说,我将设法在一段时间内通过一些请求,然后是一串ETIMEDOUT 错误。错误发生的频率比我能够通过请求的频率要高,错误与成功的比例约为 3:1。

在我自己的计算机(运行 OS X El Capitan 的 Mac)上,为给定站点运行 js 文件可以 100% 成功(即我以前从未遇到过这个问题)...所以我不确定为什么问题包含在我的 droplet 中。

任何指针将不胜感激。

 

研究/类似帖子:

 

附加信息

我还觉得值得一提的是,我试图主动提出请求的网站在脚本和网络爬虫方面存在问题,所以如果他们尝试了书中的所有内容以防止这种情况发生,我不会感到惊讶.

 

可能的原因

  • IP 地址阻塞 --> (还)不是这样,因为我仍然偶尔会收到来自服务器的响应 我无法再收到任何来自服务器的某种响应。这可能是原因,但我对他们如何做到这一点感到非常困惑。在我的本地机器上没有问题,从浏览器在我的 droplet 上请求他们的页面也没有问题,但是然后这个。

  • 我的请求的“速率限制” --> 如果是这种情况,我想知道为什么这会发生在我的服务器上,而不是在我的本地机器

  • 我提出请求的方式(即不通过浏览器)。 --> 我不认为是这种情况,因为我可以运行第一个脚本在我的本地计算机上具有 100% 的响应率(除非我的本地计算机在将我的请求发送到他们的服务器之前执行了某些操作)。

  • 系统本身。我只在我的 Mac 上测试了第一个脚本。也许代码在不同的操作系统/系统上运行不同..?

 

使用 traceroute 进行诊断

所以按照@RabeeAbdelWahab 的建议,我尝试 用traceroute 诊断问题。但是,我实际上对网络一无所知,所以我不确定如何进行。这是一个示例输出:

traceroute to <> (XXX.XXX.XXX.XXX), 30 hops max, 60 byte packets
 1  45.55.192.254 (45.55.192.254)  8.903 ms  8.879 ms  8.865 ms
 2  162.243.188.229 (162.243.188.229)  1.028 ms 162.243.188.233 (162.243.188.233)  0.986 ms  1.004 ms
 3  xe-0-9-0-17.r08.nycmny01.us.bb.gin.ntt.net (129.250.204.113)  1.923 ms  1.918 ms nyk-b3-link.telia.net (62.115.45.5)  1.587 ms
 4  ae-11.amazon.nycmny01.us.bb.gin.ntt.net (129.250.201.138)  1.935 ms ae-10.amazon.nycmny01.us.bb.gin.ntt.net (129.250.201.134)  1.586 ms *
 5  nyk-b5-link.telia.net (213.155.131.137)  1.822 ms * *
 6  * * 62.115.32.130 (62.115.32.130)  1.361 ms
 7  * * *
 8  * * *
 9  * * *
10  54.239.110.157 (54.239.110.157)  33.817 ms * 54.239.110.133 (54.239.110.133)  27.683 ms
11  54.239.111.17 (54.239.111.17)  8.193 ms 205.251.244.128 (205.251.244.128)  7.883 ms 54.239.111.23 (54.239.111.23)  9.319 ms
12  205.251.245.55 (205.251.245.55)  8.253 ms 54.239.110.175 (54.239.110.175)  24.601 ms 205.251.244.195 (205.251.244.195)  8.250 ms
13  * 54.239.111.27 (54.239.111.27)  9.319 ms 54.239.111.29 (54.239.111.29)  9.290 ms
14  * * *
15  54.239.111.23 (54.239.111.23)  9.136 ms * *
16  * * *
17  * * *
18  * * *
19  * * *
20  * * *
21  * * *
22  * * *
23  * * *
24  * * *
25  * * *
26  * * *
27  * * *
28  * * *
29  * * *
30  * * *

 

所以在多次运行traceroute 之后,我注意到以下模式:

  • “***”输出开始于第 15 跳之后的某个时间点或稍晚一点。

  • “* * *”跃点之前的最后一个 IP 地址似乎在相同的地址之间交替出现:205.251.XXX.XXX(这种情况稍微多一些)或54.239.XXX.XXX。在某些特定情况下,我会得到一个类似72.21.222.155 的地址。

此外,我在以下情况下没有发现任何差异:

  • 使用-m 255 选项运行traceroute(即最大跳数)。

  • 使用-I 选项运行traceroute

  • 使用-e 选项运行traceroute

  • 使用-p 80-p 25 选项运行traceroute

  • 在与相关液滴位于同一数据中心的不同液滴上运行 traceroute

 

通过 ping 进行诊断

使用ping,这是我可以连接和无法连接的网站的运行列表:

可以连接

  • google.com

  • facebook.com

  • reddit.com

  • github.com

  • stackoverflow.com

  • youtube.com

  • twitter.com

无法连接:

  • amazon.com

  • microsoft.com

  • apple.com

  • walmart.com

  • paypal.com

  • cnn.com

  • nyt.org

  • wolframalpha.com

观察:为什么我似乎能够连接到具有“社交”功能(否则不能)的网站?

 

显然,网站不返回 ICMP 的回复是很常见的(其中 是pingtraceroute 使用的)。请忽略以上...

 

其他发现

所以我注意到,如果我修改我的请求以获取额外的“用户代理”标头(下面提供的代码示例),我最初能够取回 html 响应。

var request = require('request');

var requestOptions = 
{
    url: 'http://www.supremenewyork.com/some/route',
    headers: {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'}
};

request(requestOptions, function(err, res, body) { 
  if (err) {
    console.log(err);
    return;
  }

  console.log('body:', body);
});

我实际上可以多次使用上述方法获得回复。之后,似乎我的所有连接都导致了上述 ETIMEDOUT 错误。然后我将不得不等待很长一段时间,然后冲洗、清洗并重复。

我实际上为 以上(即接收带有和不带有“用户代理”的响应 标题)并得到0.8493的p值......所以没有统计学意义 两者之间。再次,请忽略上述...

【问题讨论】:

  • 您是否尝试过从您的 droplet 跟踪请求?并将其与本地traceroute进行比较
  • @RabeeAbdelWahab - 好吧,我明白了。听起来很有用,我去看看。谢谢!
  • 该建议最终以两个请求给出相同的结果,我会尝试看看我是否能够添加其他可能有用的东西
  • 您的 DO 托管在纽约,那么您当前的位置呢,您也是纽约人吗?当您增加超时设置时会发生什么?再等一段时间后出现同样的错误?您是否尝试过使用 nodejs 的 http.ClientRequest 而不是 request 包?

标签: node.js network-programming hosting digital-ocean node-request


【解决方案1】:

由于您说他们有问题并试图防止刮擦或其他事情,您可能会受到这些努力的影响。为什么您需要如此频繁地访问他们的页面?

我认为,如果您真的希望它起作用,您将需要欺骗他们的反抓取系统(防火墙或其他)。因此,您可以尝试在不同的数据中心/城市中使用 Droplet,也可以尝试添加标题以模仿 Web 浏览器。 User-Agent 将是我尝试的第一个。

var options = { headers: { "user-agent":
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko)  Chrome/41.0.2228.0 Safari/537.36"}, url: "www.supremenewyork.com"}

另外,请确保您不要经常访问他们的网站并受到限制。

【讨论】:

  • 为了解决您的第一个问题,我不相信我提出了很多要求。绝对不是数百个,但另一方面比典型的用户通过浏览器与他们的网站交互的方式要多。无论哪种方式,我肯定会尽量减少我提出的请求数量,以防他们确实设置了某种“检测”系统(尽管我倾向于相信他们没有那么能力)。
  • 解决您的主要观点:在我的帖子中,您会发现我实际上已经尝试设置用户代理(在“其他发现”下)。但是,它似乎并没有比发送没有附加该标头的请求产生更好的结果。这一点,再加上我从来没有遇到过从本地机器发出请求的问题(即使用我的帖子中提到的脚本,我得到了 100% 的响应率),这让我怀疑我是如何发出请求的问题。也就是说,我也不确定改变液滴的位置是否能达到我想要的效果。
  • 无论如何,感谢您抽出宝贵的时间进行回复,我绝对欢迎您提出更多建议和想法。非常感谢!! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多