Node.js
Performances Node.js
Recherche…
Boucle d'événement
Exemple d'opération de blocage
let loop = (i, max) => {
while (i < max) i++
return i
}
// This operation will block Node.js
// Because, it's CPU-bound
// You should be careful about this kind of code
loop(0, 1e+12)
Exemple d'opération IO non bloquante
let i = 0
const step = max => {
while (i < max) i++
console.log('i = %d', i)
}
const tick = max => process.nextTick(step, max)
// this will postpone tick run step's while-loop to event loop cycles
// any other IO-bound operation (like filesystem reading) can take place
// in parallel
tick(1e+6)
tick(1e+7)
console.log('this will output before all of tick operations. i = %d', i)
console.log('because tick operations will be postponed')
tick(1e+8)
En termes plus simples, Event Loop est un mécanisme de file d'attente à thread unique qui exécute votre code lié à l'UC jusqu'à la fin de son exécution et le code lié aux E / S de manière non bloquante.
Cependant, Node.js sous le tapis utilise plusieurs threads pour certaines de ses opérations via libuv Library.
Considérations de performance
- Les opérations non bloquantes ne bloqueront pas la file d'attente et n'affecteront pas les performances de la boucle.
- Cependant, les opérations liées au processeur bloquent la file d'attente, vous devez donc faire attention à ne pas effectuer d'opérations liées au processeur dans votre code Node.js.
Node.js non-blocs IO car il décharge le travail sur le noyau du système d'exploitation, et lorsque l'opération IO fournit des données ( en tant qu'événement ), il notifiera votre code avec les rappels fournis.
Augmenter les maxSockets
Les bases
require('http').globalAgent.maxSockets = 25
// You can change 25 to Infinity or to a different value by experimenting
Node.js utilise par défaut maxSockets = Infinity
en même temps (depuis la v0.12.0 ). Jusqu'à Node v0.12.0, la valeur par défaut était maxSockets = 5
(voir v0.11.0 ). Ainsi, après plus de 5 demandes, ils seront mis en file d'attente. Si vous voulez une concurrence, augmentez ce nombre.
Définir votre propre agent
http
API http
utilise un " Agent global " . Vous pouvez fournir votre propre agent. Comme ça:
const http = require('http')
const myGloriousAgent = new http.Agent({ keepAlive: true })
myGloriousAgent.maxSockets = Infinity
http.request({ ..., agent: myGloriousAgent }, ...)
Désactiver complètement la mise en commun des sockets
const http = require('http')
const options = {.....}
options.agent = false
const request = http.request(options)
Pièges
Vous devriez faire la même chose pour les API
https
si vous voulez les mêmes effetsAttention, par exemple, AWS utilisera 50 au lieu d'
Infinity
.
Activer gzip
const http = require('http')
const fs = require('fs')
const zlib = require('zlib')
http.createServer((request, response) => {
const stream = fs.createReadStream('index.html')
const acceptsEncoding = request.headers['accept-encoding']
let encoder = {
hasEncoder : false,
contentEncoding: {},
createEncoder : () => throw 'There is no encoder'
}
if (!acceptsEncoding) {
acceptsEncoding = ''
}
if (acceptsEncoding.match(/\bdeflate\b/)) {
encoder = {
hasEncoder : true,
contentEncoding: { 'content-encoding': 'deflate' },
createEncoder : zlib.createDeflate
}
} else if (acceptsEncoding.match(/\bgzip\b/)) {
encoder = {
hasEncoder : true,
contentEncoding: { 'content-encoding': 'gzip' },
createEncoder : zlib.createGzip
}
}
response.writeHead(200, encoder.contentEncoding)
if (encoder.hasEncoder) {
stream = stream.pipe(encoder.createEncoder())
}
stream.pipe(response)
}).listen(1337)