J'essaie actuellement de simuler un demi-million d'appareils IoT pour pousser la charge utile vers Azure IoT Hub à l'aide de nodejs. Étant donné que le nœud est de nature multithread, son hub iot est inondé de données et je reçois des erreurs réseau.
J'ai également essayé la méthode async / await, mais cela prend beaucoup de temps pour pousser les données vers IoT Hub.
Existe-t-il un moyen d'exécuter seulement 100 appels en parallèle, d'attendre qu'ils se terminent tous, puis d'exécuter les 100 prochains appels dans le nœud?
Très apprécié!
3 Réponses :
Vous pouvez facilement utiliser la carte de bluebird Promise avec l'option de concurrence. Cela traite les enregistrements max comme mentionné dans la concurrence, avant de prendre le prochain lot. exemple:
Promise.map ([], {concurrence: 100})
Existe-t-il un moyen d'utiliser l'option concurrence dans un simple appel .all standard? Et si nous n'avons pas besoin d'utiliser la carte
L'option @ user2402616 concurrence est fournie par bluebird ce n'est pas une fonctionnalité js inhérente. Il ne peut pas être utilisé avec promise.all
Créez vos lots sous la forme d'un tableau imbriqué de Promise , puis utilisez Promise.all
sur chaque lot dans une boucle que attend s pour chaque Promise.all à résoudre.
// This is a mock request function, could be a `request` call
// or a database query; whatever it is, it MUST return a Promise.
const sendRequest = () => {
return new Promise((resolve) => {
setTimeout(() => {
console.log('request sent')
resolve()
}, 1000)
})
}
// 5 batches * 2 requests = 10 requests.
const batches = Array(5).fill(Array(2).fill(sendRequest))
;(async function() {
for (const batch of batches) {
try {
console.log('-- sending batch --')
await Promise.all(batch.map(f => f()))
} catch(err) {
console.error(err)
}
}
})()
Comment passer une URL pour envoyer la méthode rquest. Par exemple, j'ai une liste d'URL var urls = ['' exemple. com / A ", '' https: //example.com/B ", '' Exemple de " rel="nofollow noreferrer">. com / C "] et ainsi de suite et je souhaite exécuter ces API par lots. Mais je ne sais pas comment transmettre l'URL?
limited-request-queue pourrait être utilisé pour mettre la requête en file d'attente. Il existe des options pour définir le nombre maximal de connexions à un moment donné. Vous trouverez ci-dessous le code que nous avons utilisé pour envoyer 5 requêtes par seconde. De plus, il n'y aura que 5 demandes envoyées à un moment donné.
/*
Request passed to Targer App (5 requests per seconds)
Get the response for each request and passed the response to Source App
maxSockets: The maximum number of connections allowed at any given time. A value of 0 will prevent anything from going out. A value of Infinity will provide no concurrency limiting.
maxSocketsPerHost:The maximum number of connections per host allowed at any given time. A value of 0 will prevent anything from going out. A value of Infinity will provide no per-host concurrency limiting.
rateLimit: The number of milliseconds to wait before each maxSocketsPerHost
*/
var queue1 = new RequestQueue({'maxSockets': 5, 'maxSocketsPerHost': 5, 'rateLimit': 1000}, {
item: function(input, done) {
request(input.url, function(error, response) {
input.res.send(response.body);
done();
});
},
end: function() {
console.log("Queue 1 completed!");
}
});
//To queue request - A for loop could be used to send multiple request
queue1.enqueue({'url': ''});
Les runtimes Javascript sont à thread unique.
Le problème n'est pas que son multithread, mais que son asynchrone.