Node.js Demande d'OBTENIR ETIMEDOUT & ESOCKETTIMEDOUT
Je suis en utilisant Node.js - async & demande module d'analyse de plus de 100 millions de sites web et je garde de heurter les erreurs ESOCKETTIMEDOUT
& ETIMEDOUT
après quelques minutes.
Il fonctionne à nouveau après avoir redémarrer le script. Il ne semble pas être la limite de connexions question parce que je peux encore faire resolve4, resolveNs, resolveMx et aussi curl
sans délai.
Voyez-vous un problème avec le code? ou des conseils? J'aimerais pousser l'asynchrone.la file d'attente() simultanéité à au moins 1000. Merci.
var request = require('request'),
async = require('async'),
mysql = require('mysql'),
dns = require('dns'),
url = require('url'),
cheerio = require('cheerio'),
iconv = require('iconv-lite'),
charset = require('charset'),
config = require('./spy.config'),
pool = mysql.createPool(config.db);
iconv.skipDecodeWarning = true;
var queue = async.queue(function (task, cb) {
dns.resolve4('www.' + task.domain, function (err, addresses) {
if (err) {
//
//Do something
//
setImmediate(function () {
cb()
});
} else {
request({
url: 'http://www.' + task.domain,
method: 'GET',
encoding: 'binary',
followRedirect: true,
pool: false,
pool: { maxSockets: 1000 },
timeout: 15000 //15 sec
}, function (error, response, body) {
//console.info(task);
if (!error) {
//If ok, do something
} else {
//If not ok, do these
console.log(error);
//It keeps erroring here after few minutes, resolve4, resolveNs, resolveMx still work here.
//{ [Error: ETIMEDOUT] code: 'ETIMEDOUT' }
//{ [Error: ESOCKETTIMEDOUT] code: 'ESOCKETTIMEDOUT' }
var ns = [],
ip = [],
mx = [];
async.parallel([
function (callback) {
//Resolves the domain's name server records
dns.resolveNs(task.domain, function (err, addresses) {
if (!err) {
ns = addresses;
}
callback();
});
}, function (callback) {
//Resolves the domain's IPV4 addresses
dns.resolve4(task.domain, function (err, addresses) {
if (!err) {
ip = addresses;
}
callback();
});
}, function (callback) {
//Resolves the domain's MX records
dns.resolveMx(task.domain, function (err, addresses) {
if (!err) {
addresses.forEach(function (a) {
mx.push(a.exchange);
});
}
callback();
});
}
], function (err) {
if (err) return next(err);
//do something
});
}
setImmediate(function () {
cb()
});
});
}
});
}, 200);
//When the queue is emptied we want to check if we're done
queue.drain = function () {
setImmediate(function () {
checkDone()
});
};
function consoleLog(msg) {
//console.info(msg);
}
function checkDone() {
if (queue.length() == 0) {
setImmediate(function () {
crawlQueue()
});
} else {
console.log("checkDone() not zero");
}
}
function query(sql) {
pool.getConnection(function (err, connection) {
if (!err) {
//console.log(sql);
connection.query(sql, function (err, results) {
connection.release();
});
}
});
}
function crawlQueue() {
pool.getConnection(function (err, connection) {
if (!err) {
var sql = "SELECT * FROM domain last_update < (UNIX_TIMESTAMP() - 2592000) LIMIT 500";
connection.query(sql, function (err, results) {
if (!err) {
if (results.length) {
for (var i = 0, len = results.length; i < len; ++i) {
queue.push({"id": results[i]['id'], "domain": results[i]['domain'] });
}
} else {
process.exit();
}
connection.release();
} else {
connection.release();
setImmediate(function () {
crawlQueue()
});
}
});
} else {
setImmediate(function () {
crawlQueue()
});
}
});
}
setImmediate(function () {
crawlQueue()
});
Et des limites du système sont assez élevés.
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size 0 unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 257645 257645 processes
Max open files 500000 500000 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 257645 257645 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
sysctl
net.ipv4.ip_local_port_range = 10000 61000
pourquoi la piscine (sur demande) deux fois?
Il est de désactiver la piscine. Je reçois encore des erreurs, avec ou sans piscine et le maxSockets.
avez-vous été en mesure de trouver la cause?
Voir ma réponse ici pour une solution: stackoverflow.com/questions/35387264/...
Il est de désactiver la piscine. Je reçois encore des erreurs, avec ou sans piscine et le maxSockets.
avez-vous été en mesure de trouver la cause?
Voir ma réponse ici pour une solution: stackoverflow.com/questions/35387264/...
OriginalL'auteur Tan Hong Tat | 2014-06-20
Vous devez vous connecter pour publier un commentaire.
Par défaut, le Nœud a 4 travailleurs pour résoudre les requêtes DNS. Si votre requête DNS prend du temps-ish temps, la demande se bloque sur le DNS de phase, et le problème est exactement
ESOCKETTIMEDOUT
ouETIMEDOUT
.Essayez d'augmenter votre uv taille du pool de threads:
ou dans
index.js
(ou partout où votre point d'entrée est):J'ai reproduit cette localement en ralentissant les réponses du serveur DNS à l'aide de tc.
Ne fonctionne pas pour moi non plus.
OriginalL'auteur Motiejus Jakštys
J'ai eu le même problème. Il est résolu à l'aide de l'agent": false," dans l'option de requête après la lecture de cette discussion.
10/31/2017
L'original de la réponse ci-dessus ne semble pas résoudre complètement le problème. La dernière solution que nous avons trouvé est d'utiliser l'option persistantes dans un agent. Par exemple:
Nœud par défaut de la piscine semble défaut de keepAlive=false, ce qui provoque une nouvelle connexion créée sur chaque demande. Lorsqu'un trop grand nombre connexions sont créées dans un court laps de temps, l'erreur ci-dessus serait de surface. Ma conjecture est que l'un ou plusieurs routeurs sur le chemin d'accès au service de blocs de demande de connexion, probablement dans le cadre d'une suspicion de déni De Service (ddos). En tout cas, l'exemple de code ci-dessus complètement résolu notre problème.
OriginalL'auteur Alex W