千个并发请求 - EAI_AGAIN/ECONNRESET 错误
Thousand of concurrent requests - EAI_AGAIN/ECONNRESET error
我需要在一个小时内执行一百万个 API 调用(服务器可以处理这么多流量),为此,我使用节点来并行 运行 多个请求,但是当我尝试 运行 ~1000 个并发请求时,我不断收到这些错误:
EAI_AGAIN
{ [Error: getaddrinfo EAI_AGAIN google.com:80]
code: 'EAI_AGAIN',
errno: 'EAI_AGAIN',
syscall: 'getaddrinfo',
hostname: 'google.com',
host: 'google.com',
port: 80 }
ECONNRESET
{
[Error: read ECONNRESET] code: 'ECONNRESET',
errno: 'ECONNRESET',
syscall: 'read'
}
如何在不将请求减少到 500 的情况下防止这种情况发生?
这是一个代码示例,当 运行 一次发送 500 个请求时,它可以完美运行,但当限制超过 1000 时就会失败。(您的限制可能不同)。
"use strict";
const http = require('http');
http.globalAgent.maxSockets = Infinity;
const async = require('async');
const request = require("request");
let success = 0;
let error = 0;
function iterateAsync() {
let rows = [];
for (let i = 0; i < 500; i++) {
rows.push(i);
}
console.time("Requests");
async.each(
rows,
(item, callback) => get(callback),
(err) => {
console.log("Failed: " + error);
console.log("Success: " + success);
console.timeEnd("Requests");
});
}
function get(callback) {
request("http://example.com", (err, response, body) => {
if (err) {
console.log(err);
error++;
return callback();
}
success++;
callback();
});
}
iterateAsync();
我添加了 http.globalAgent.maxSockets = Infinity;
尽管是默认值。
500 次请求
1000 次请求
附加信息:
我运行正在 ubuntu 14.04 和 15.04 上进行测试,我修改了 file-max
、tcp_fin_timeout
、 tcp_tw_reuse
、ip_local_port_range
/etc/sysctl.conf
中的默认值,如本 post
中所述
- 文件最大: 100000
- tcp_fin_timeout: 15
- tcp_tw_reuse: 1
- ip_local_port_range: 10000 65000
在 /etc/security/limits.conf
中添加了以下行
* soft nofile 100000
* hard nofile 100000
使用这个值,我仍然收到错误。
我已阅读所有其他类似帖子:
- Increasing the maximum number of tcp/ip connections in linux
有什么方法可以让我知道我的系统可以管理的并发请求的确切数量?
这是我在@jfriend00 输入后解决它的方法。
我使用 dns.resolve4
解析主机 IP 地址,然后使用 IP 执行请求,这样错误就消失了,我可以在更短的时间内执行更多请求。
"use strict";
const dns = require("dns");
const http = require('http');
http.globalAgent.maxSockets = Infinity;
const async = require('async');
const request = require("request");
let success = 0;
let error = 0;
function iterateAsync() {
let rows = [];
for (let i = 0; i < 500; i++) {
rows.push(i);
}
console.time("Requests");
dns.resolve4("example.com", (err, addresses) =>{ //Resolve host and obtain IP address
if(err) //Handle error
return false;
async.each(
rows,
(item, callback) => get(`http://${addresses[0]}`, callback),
(err) => {
console.log("Failed: " + error);
console.log("Success: " + success);
console.timeEnd("Requests");
});
});
}
function get(host, callback) {
request(host, (err, response, body) => {
if (err) {
console.log(err);
error++;
return callback();
}
success++;
callback();
});
}
//Start requests
iterateAsync();
输出:
Failed: 0
Success: 500
Requests: 6295.799ms
我需要在一个小时内执行一百万个 API 调用(服务器可以处理这么多流量),为此,我使用节点来并行 运行 多个请求,但是当我尝试 运行 ~1000 个并发请求时,我不断收到这些错误:
EAI_AGAIN
{ [Error: getaddrinfo EAI_AGAIN google.com:80]
code: 'EAI_AGAIN',
errno: 'EAI_AGAIN',
syscall: 'getaddrinfo',
hostname: 'google.com',
host: 'google.com',
port: 80 }
ECONNRESET
{
[Error: read ECONNRESET] code: 'ECONNRESET',
errno: 'ECONNRESET',
syscall: 'read'
}
如何在不将请求减少到 500 的情况下防止这种情况发生?
这是一个代码示例,当 运行 一次发送 500 个请求时,它可以完美运行,但当限制超过 1000 时就会失败。(您的限制可能不同)。
"use strict";
const http = require('http');
http.globalAgent.maxSockets = Infinity;
const async = require('async');
const request = require("request");
let success = 0;
let error = 0;
function iterateAsync() {
let rows = [];
for (let i = 0; i < 500; i++) {
rows.push(i);
}
console.time("Requests");
async.each(
rows,
(item, callback) => get(callback),
(err) => {
console.log("Failed: " + error);
console.log("Success: " + success);
console.timeEnd("Requests");
});
}
function get(callback) {
request("http://example.com", (err, response, body) => {
if (err) {
console.log(err);
error++;
return callback();
}
success++;
callback();
});
}
iterateAsync();
我添加了 http.globalAgent.maxSockets = Infinity;
尽管是默认值。
500 次请求
1000 次请求
附加信息:
我运行正在 ubuntu 14.04 和 15.04 上进行测试,我修改了 file-max
、tcp_fin_timeout
、 tcp_tw_reuse
、ip_local_port_range
/etc/sysctl.conf
中的默认值,如本 post
- 文件最大: 100000
- tcp_fin_timeout: 15
- tcp_tw_reuse: 1
- ip_local_port_range: 10000 65000
在 /etc/security/limits.conf
中添加了以下行* soft nofile 100000
* hard nofile 100000
使用这个值,我仍然收到错误。
我已阅读所有其他类似帖子:
- Increasing the maximum number of tcp/ip connections in linux
有什么方法可以让我知道我的系统可以管理的并发请求的确切数量?
这是我在@jfriend00 输入后解决它的方法。
我使用 dns.resolve4
解析主机 IP 地址,然后使用 IP 执行请求,这样错误就消失了,我可以在更短的时间内执行更多请求。
"use strict";
const dns = require("dns");
const http = require('http');
http.globalAgent.maxSockets = Infinity;
const async = require('async');
const request = require("request");
let success = 0;
let error = 0;
function iterateAsync() {
let rows = [];
for (let i = 0; i < 500; i++) {
rows.push(i);
}
console.time("Requests");
dns.resolve4("example.com", (err, addresses) =>{ //Resolve host and obtain IP address
if(err) //Handle error
return false;
async.each(
rows,
(item, callback) => get(`http://${addresses[0]}`, callback),
(err) => {
console.log("Failed: " + error);
console.log("Success: " + success);
console.timeEnd("Requests");
});
});
}
function get(host, callback) {
request(host, (err, response, body) => {
if (err) {
console.log(err);
error++;
return callback();
}
success++;
callback();
});
}
//Start requests
iterateAsync();
输出:
Failed: 0
Success: 500
Requests: 6295.799ms