developer tip

멀티 코어 머신의 Node.js

copycodes 2020. 10. 3. 10:58
반응형

멀티 코어 머신의 Node.js


Node.js를이 흥미로운 보이는, 하지만 뭔가 그리워한다 - Node.js를 단일 프로세스 및 스레드에서 실행 만 조정되지 않습니다?

그렇다면 멀티 코어 CPU 및 멀티 CPU 서버에 대해 어떻게 확장됩니까? 결국 가능한 한 단일 스레드 서버를 빠르게 만드는 것이 좋지만 높은로드의 경우 여러 CPU를 사용하고 싶습니다. 응용 프로그램을 더 빠르게 만드는 것도 마찬가지입니다. 오늘날에는 여러 CPU를 사용하고 작업을 병렬화하는 방법이 있습니다.

Node.js는이 그림에 어떻게 들어 맞습니까? 어떻게 든 여러 인스턴스를 배포하는 아이디어입니까?


[ 이 게시물은 2012 년 9 월 2 일 (위보다 최신) 현재 최신입니다. ]

Node.js는 절대적으로 멀티 코어 머신에서 확장됩니다.

예, Node.js는 프로세스 당 하나의 스레드입니다. 이것은 매우 신중한 설계 결정이며 잠금 의미를 처리 할 필요가 없습니다. 이에 동의하지 않는다면 멀티 스레드 코드를 디버깅하는 것이 얼마나 어려운지 아직 깨닫지 못했을 것입니다. Node.js 프로세스 모델에 대한 더 자세한 설명과 이것이 왜 이런 방식으로 작동하는지 (그리고 왜 다중 스레드를 지원하지 않는지), 저의 다른 게시물을 읽어보십시오 .

그렇다면 16 코어 박스를 어떻게 활용합니까?

두 가지 방법:

  • 이미지 인코딩과 같은 대용량 컴퓨팅 작업의 경우 Node.js는 하위 프로세스를 시작하거나 추가 작업자 프로세스에 메시지를 보낼 수 있습니다. 이 디자인에서는 이벤트 흐름을 관리하는 스레드 하나와 무거운 컴퓨팅 작업을 수행하는 N 개의 프로세스와 나머지 15 개의 CPU를 씹게됩니다.
  • 웹 서비스의 처리량을 확장하려면 하나의 상자에서 코어 당 하나씩 여러 Node.js 서버를 실행하고 이들간에 요청 트래픽을 분할해야합니다. 이는 뛰어난 CPU 친 화성을 제공하며 코어 수에 따라 거의 선형 적으로 처리량을 확장합니다.

웹 서비스의 처리량 확장

v6.0.X부터 Node.js에는 즉시 클러스터 모듈 이 포함되어 있으므로 단일 포트에서 수신 할 수있는 여러 노드 작업자를 쉽게 설정할 수 있습니다. 이것은 npm을 통해 사용할 수있는 이전 learnboost "클러스터"모듈과 동일하지 않습니다 .

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
} else {
  http.Server(function(req, res) { ... }).listen(8000);
}

작업자는 새로운 연결을 수락하기 위해 경쟁하며로드가 가장 적은 프로세스가 이길 가능성이 높습니다. 그것은 꽤 잘 작동하고 멀티 코어 박스에서 처리량을 상당히 높일 수 있습니다.

여러 코어를 관리하기에 충분한로드가있는 경우 몇 가지 작업도 더 수행해야합니다.

  1. Nginx 또는 Apache 와 같은 웹 프록시 뒤에서 Node.js 서비스를 실행합니다. 연결 조절을 수행하고 (오버로드 조건으로 인해 상자가 완전히 중단되기를 원하지 않는 한) URL을 다시 작성하고 정적 콘텐츠를 제공하고 기타 하위 서비스를 프록시 할 수 있습니다.

  2. 작업자 프로세스를 주기적으로 재활용하십시오. 장기 실행 프로세스의 경우 작은 메모리 누수가 결국 더해집니다.

  3. 로그 수집 / 모니터링 설정


추신 : 다른 게시물의 의견에서 Aaron과 Christopher 사이에 토론이 있습니다 (이 글을 쓰는 시점에서 최상위 게시물). 이에 대한 몇 가지 의견 :

  • 공유 소켓 모델은 여러 프로세스가 단일 포트에서 수신 대기하고 새로운 연결을 수락하기 위해 경쟁 할 수 있도록하는 데 매우 편리합니다. 개념적으로는 각 프로세스가 단일 연결 만 허용 한 다음 종료된다는 중요한 경고와 함께 미리 분기 된 Apache를 생각할 수 있습니다. Apache의 효율성 손실은 새 프로세스를 포크하는 오버 헤드에 있으며 소켓 작업과 관련이 없습니다.
  • Node.js의 경우 N 작업자가 단일 소켓에서 경쟁하게하는 것은 매우 합리적인 솔루션입니다. 대안은 Nginx와 같은 온 박스 프런트 엔드를 설정하고 새 연결을 할당하기 위해 작업자간에 교대로 프록시 트래픽을 개별 작업자로 보내는 것입니다. 두 솔루션의 성능 특성은 매우 유사합니다. 그리고 위에서 언급했듯이 Nginx (또는 대안)가 노드 서비스를 앞쪽에두고 싶을 가능성이 높으므로 여기서 선택은 실제로 다음 중 하나입니다.

공유 포트 : nginx (port 80) --> Node_workers x N (sharing port 3000 w/ Cluster)

vs

개별 포트 : nginx (port 80) --> {Node_worker (port 3000), Node_worker (port 3001), Node_worker (port 3002), Node_worker (port 3003) ...}

개별 포트 설정에는 틀림없이 몇 가지 이점이 있지만 (프로세스 간 결합이 적고로드 밸런싱 결정이 더 정교 할 수 있음) 확실히 설정 작업이 더 많고 기본 제공 클러스터 모듈은 낮습니다. -대부분의 사람들에게 적합한 복잡성 대안.


One method would be to run multiple instances of node.js on the server and then put a load balancer (preferably a non-blocking one like nginx) in front of them.


Ryan Dahl answers this question in the tech talk he gave at Google last summer. To paraphrase, "just run multiple node processes and use something sensible to allow them to communicate. e.g. sendmsg()-style IPC or traditional RPC".

If you want to get your hands dirty right away, check out the spark2 Forever module. It makes spawning multiple node processes trivially easy. It handles setting up port sharing, so they can each accept connections to the same port, and also auto-respawning if you want to make sure a process is restarted if/when it dies.

UPDATE - 10/11/11: Consensus in the node community seems to be that Cluster is now the preferred module for managing multiple node instances per machine. Forever is also worth a look.


You can use cluster module. Check this.

var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
    // Fork workers.
    for (var i = 0; i < numCPUs; i++) {
        cluster.fork();
    }

    cluster.on('exit', function(worker, code, signal) {
        console.log('worker ' + worker.process.pid + ' died');
    });
} else {
    // Workers can share any TCP connection
    // In this case its a HTTP server
    http.createServer(function(req, res) {
        res.writeHead(200);
        res.end("hello world\n");
    }).listen(8000);
}

Multi-node harnesses all the cores that you may have.
Have a look at http://github.com/kriszyp/multi-node.

For simpler needs, you can start up multiple copies of node on different port numbers and put a load balancer in front of them.


As mentioned above, Cluster will scale and load-balance your app across all cores.

adding something like

cluster.on('exit', function () {
  cluster.fork();
});

Will restart any failing workers.

These days, a lot of people also prefer PM2, which handles the clustering for you and also provides some cool monitoring features.

Then, add Nginx or HAProxy in front of several machines running with clustering and you have multiple levels of failover and a much higher load capacity.


Node Js is supporting clustering to take full advantages of your cpu. If you are not not running it with cluster, then probably you are wasting your hardware capabilities.

Clustering in Node.js allows you to create separate processes which can share same server port. For example, if we run one HTTP server on Port 3000, it is one Server running on Single thread on single core of processor.

Code shown below allow you to cluster your application. This code is official code represented by Node.js.

var cluster = require('cluster');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
    // Fork workers.
    for (var i = 0; i < numCPUs; i++) {
        cluster.fork();
    }

    Object.keys(cluster.workers).forEach(function(id) {
        console.log("I am running with ID : " + cluster.workers[id].process.pid);
    });

    cluster.on('exit', function(worker, code, signal) {
        console.log('worker ' + worker.process.pid + ' died');
    });
} else {

    //Do further processing.
}

check this article for the full tutorial


Future version of node will allow you to fork a process and pass messages to it and Ryan has stated he wants to find some way to also share file handlers, so it won't be a straight forward Web Worker implementation.

At this time there is not an easy solution for this but it's still very early and node is one of the fastest moving open source projects I've ever seen so expect something awesome in the near future.


Spark2 is based on Spark which is now no longer maintained. Cluster is its successor, and it has some cool features, like spawning one worker process per CPU core and respawning dead workers.


I'm using Node worker to run processes in a simple way from my main process. Seems to be working great while we wait for the official way to come around.


The new kid on the block here is LearnBoost's "Up".

It provides "Zero-downtime reloads" and additionally creates multiple workers (by default the number of CPUs, but it is configurable) to provide the best of all Worlds.

It is new, but seems to be pretty stable, and I'm using it happily in one of my current projects.


You may run your node.js application on multiple cores by using the cluster module on combination with os module which may be used to detect how many CPUs you have.

For example let's imagine that you have a server module that runs simple http server on the backend and you want to run it for several CPUs:

// Dependencies.
const server = require('./lib/server'); // This is our custom server module.
const cluster = require('cluster');
const os = require('os');

 // If we're on the master thread start the forks.
if (cluster.isMaster) {
  // Fork the process.
  for (let i = 0; i < os.cpus().length; i++) {
    cluster.fork();
  }
} else {
  // If we're not on the master thread start the server.
  server.init();
}


The cluster module allows you to utilise all cores of your machine. In fact you can take advantage of this in just 2 commands and without touching your code using a very popular process manager pm2.

npm i -g pm2
pm2 start app.js -i max

It's also possible to design the web-service as several stand alone servers that listen to unix sockets, so that you can push functions like data processing into seperate processes.

This is similar to most scrpting/database web server architectures where a cgi process handles business logic and then pushes and pulls the data via a unix socket to a database.

the difference being that the data processing is written as a node webserver listening on a port.

it's more complex but ultimately its where multi-core development has to go. a multiprocess architecture using multiple components for each web request.


It's possible to scale NodeJS out to multiple boxes using a pure TCP load balancer (HAProxy) in front of multiple boxes running one NodeJS process each.

If you then have some common knowledge to share between all instances you could use a central Redis store or similar which can then be accessed from all process instances (e.g. from all boxes)

참고URL : https://stackoverflow.com/questions/2387724/node-js-on-multi-core-machines

반응형