수색…


이벤트 루프

차단 작업 예제

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)

논 블로킹 IO 작동 예

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)

이벤트 루프 다이어그램

간단히 말하면 이벤트 루프는 실행이 끝날 때까지 CPU 바운드 코드를 실행하고 비 차단 방식으로 IO 바운드 코드를 실행하는 단일 스레드 큐 메커니즘입니다.

그러나 카펫 아래의 Node.js는 libuv 라이브러리를 통해 멀티 스레딩을 사용합니다.

성능 고려 사항

  • 비 블로킹 연산은 큐를 차단하지 않으며 루프의 성능에 영향을 미치지 않습니다.
  • 그러나 CPU 바인딩 작업은 큐를 차단하므로 Node.js 코드에서 CPU 바인딩 작업을 수행하지 않도록주의해야합니다.

Node.js는 운영 체제 커널로 작업을 오프로드하기 때문에 IO를 차단하지 않으며 IO 작업이 데이터를 이벤트로 제공하면 제공된 콜백으로 코드를 알립니다.

maxSockets 늘리기

기초

require('http').globalAgent.maxSockets = 25

// You can change 25 to Infinity or to a different value by experimenting

Node.js는 기본적으로 maxSockets = Infinity 를 동시에 사용합니다 ( v0.12.0 부터). 노드 v0.12.0까지, 기본값은 maxSockets = 5 ( v0.11.0 참조)입니다. 따라서 5 개 이상의 요청이있을 경우 대기열에 들어갑니다. 동시성을 원하면이 수를 늘리십시오.

나만의 에이전트 설정

http API가 " 글로벌 에이전트 "를 사용 중 입니다. 자신의 에이전트를 제공 할 수 있습니다. 이렇게 :

const http = require('http')
const myGloriousAgent = new http.Agent({ keepAlive: true })
myGloriousAgent.maxSockets = Infinity

http.request({ ..., agent: myGloriousAgent }, ...)

소켓 풀링을 완전히 끄기

const http = require('http')
const options = {.....}

options.agent = false

const request = http.request(options)

함정

  • 동일한 효과를 원하면 https API에 대해 동일한 작업을 수행해야합니다.

  • 예를 들어 AWSInfinity 대신 50을 사용합니다.

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)


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow