我每50毫秒发送一个请求(即20个请求/秒)以获取网站正文,但是执行20到30秒后,我在每个请求中均收到错误ETIMEDOUT。我设置了process.env.UV_THREADPOOL_SIZE = 128;
我尝试将THREADPOOL_SIZE设置为大于128的值。
for(let i in urls) {
setTimeout(function() {
getBody(i); //It is function with a request
},50*i);
}
request({
url:url,
method:'GET',
timeout:3000,
headers: {
'Accept': '*/*',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'
}},
(err,res) => {
包裹:请求
请帮助我,我想在一秒钟内发送大量请求。
答案 0 :(得分:0)
UV_THREADPOOL_SIZE
是limited到128,因此您不能通过该数字来增加它。
其默认大小为4,但可以在启动时通过以下方式更改 将UV_THREADPOOL_SIZE环境变量设置为任何值( 绝对最大值是128)。
第二,timeouts
模块中没有request
属性,正确的属性名称是:timeout
。
如果您正在同一服务器上并行运行多个请求,则将其设置为3000可能太低,特别是在服务器无法处理那么多请求的情况下。
这可能是您收到许多超时错误的原因之一。因此,首先增加该数字以查看是否仍然超时。
第二,有两种不同的超时类型:
超时主要有两种类型:连接超时和读取超时 超时。如果在您的计算机上点击超时,则会发生连接超时 客户端正在尝试建立与远程计算机的连接 (对应于套接字上的connect()调用)。读取超时 只要服务器速度太慢而无法发回一部分 响应。
您可以执行以下操作检查超时是否是连接超时:
if(err.connect === true) // connection timeout.
此外,如果您要访问的是同一域,则可以提高IP速度并减少超时次数,可以解析IP地址,然后直接使用IP访问服务器。
我没有测试脚本,但这是为了向您展示如何做,可能需要一个较小的修复程序
const dns = require('dns');
const { promisify } = require('util');
const URL = require('url');
const dnsResolve = promisify(dns.resolve);
const ipCache = {};
async getIP(host) {
// Use LRU cache with expiration...
if(ipCache[host]) // If it's set, it's either the resolved IP or dnsResolve Promise
return ipCache[host];
ipCache[host] = dnsResolve(host);
const [ip] = await ipCache[host]; // Wait until the promise is resolved
ipCache[host] = ip;
return ip;
}
async getBody(url) {
const { host } = new URL(url);
const ip = await getIP(host);
// Build the URL using the IP address instead of the domain
request( /* ... */)
}
您还应该限制请求,因为您可能正在泛滥自己的网络。如果您在VPS上尝试此操作,则与在本地计算机上运行脚本相比,获得的超时时间可能会更少。
例如,在AWS上,有一些经过网络优化的实例更适合于发出大量请求,使用其中一个实例,您可以比在本地计算机上发出更多成功的请求。
因此,要么是您自己的网络的限制,要么是发出请求的服务器的限制,在两种情况下,您都需要限制以避免错误。