Nodejs를 사용하는 친구 모두 노드가 단일 스레드라는 것을 알고 있습니다. 즉, 8 코어 CPU에서 실행할 때 하나의 코어의 컴퓨팅 성능 만 사용할 수 있습니다.
단일 스레딩은 항상 노드에 대한 비판 이었지만 버전 0.6의 클러스터를 도입하면이 상황이 변경되었습니다. 개발자는 클러스터에 의존하여 노드 서버를 멀티 스레드 서버로 쉽게 확장 할 수 있습니다.
클러스터 란 무엇입니까?
클러스터는 노드에서 제공하는 다중 스레드 라이브러리입니다. 사용자는이를 사용하여 여러 스레드를 생성 할 수 있습니다. 스레드는 청취 포트를 공유합니다. 이 포트에 외부 요청이 있으면 클러스터는 요청을 임의의 스레드로 전달합니다. 각 노드 스레드는 수십 개의 메가 바이트 메모리를 차지하기 때문에 PHP와 같은 각 요청에 대해 스레드를 생성하는 것은 불가능합니다. 일반적으로 생성 된 스레드의 수는 CPU 코어 수를 최대한 초과하지 않습니다.
코드 사본은 다음과 같습니다.
var cluster = require ( 'cluster');
var http = 요구 ( 'http');
var numcpus = require ( 'os'). cpus (). 길이;
if (cluster.ismaster) {
// 포크 노동자.
for (var i = 0; i <numcpus; i ++) {
cluster.fork ();
}
cluster.on ( '종료', 함수 (작업자, 코드, 신호) {
Console.log ( 'Worker' + worker.process.pid + 'die');
});
} 또 다른 {
// 작업자는 모든 TCP 연결을 공유 할 수 있습니다
//이 경우 HTTP 서버입니다
http.createserver (function (req, res) {
res.writehead (200);
Res.end ( "Hello World/N");
}). 듣기 (8000);
}
위의 코드에서 볼 수 있듯이 프로그램이 실행될 때 Cluster.ismaster가 True로 설정됩니다. cluster.fork ()을 호출 한 후 프로그램은 스레드를 생성하고 재회합니다. 현재 Cluster.ismaster가 False로 설정됩니다. 우리는 주로이 변수를 사용하여 현재 스레드가 자식 스레드에 속하는지 여부를 결정합니다.
또한 각 어린이 실이 만들어지면 충돌을 일으키지 않고 포트 8000을 듣습니다. 이것은 클러스터 공유 포트의 기능입니다.
스레드 간의 커뮤니케이션
스레드가 생성되면 메모리 나 데이터를 서로 공유하지 않습니다. 모든 데이터 교환은 Worker.send and Worker.on ( 'Message', Handler)을 통해 메인 스레드에서만 처리 할 수 있습니다. 다음은 방송 시스템의 예를 나열합니다.
코드 사본은 다음과 같습니다.
var cluster = require ( 'cluster');
var http = 요구 ( 'http');
var numcpus = require ( 'os'). cpus (). 길이;
if (cluster.ismaster) {
var 근로자 = [];
// 새 작업자를 만듭니다
기능 NewWorker () {
var worker = cluster.fork ();
// 정보를 듣습니다. 유형이 방송되면 방송으로 결정됩니다.
worker.on ( '메시지', 기능 (msg) {
if (msg.type == 'broadcast') {
var event = msg.event;
//이 방송을 모든 근로자에게 보냅니다
Workers.foreach (기능 (작업자) {
Worker.send (이벤트);
})
}
});
반환 노동자;
}
for (var i = 0; i <numcpus; i ++) {
Workers.push (NewWorker ());
}
cluster.on ( '온라인', 기능 (작업자) {
console.log ( 'Worker %d는 온라인입니다', worker.id);
})
} 또 다른 {
var worker = cluster.worker;
// 방송은 유형 방송으로 메시지를 보내는 것입니다. 이벤트는 방송 내용입니다.
worker.broadcast = function (이벤트) {
worker.send ({
유형 : '방송',
이벤트 : 이벤트
});
}
// 여기서 작업자를 사용하여 반환 된 정보를들을 수 없습니다.
process.on ( 'message', function (event) {
Console.log ( 'Worker :'+worker.id+''+event.workerid에서 복구 된 이벤트);
})
// 방송을 보내십시오
worker.broadcast ({
메시지 : '온라인',
Workerid : Worker.id
})
}
알아야 할 문제
또한 데이터는 스레드간에 공유 할 수 없으며 모든 데이터 교환은 스레드 간의 통신을 통해서만 교환 할 수 있다고 언급합니다. 또한 교환 된 데이터는 직렬화 가능하므로 기능, 파일 디스크립터 및 HTTPRPRONSE는 전달할 수 없습니다.
클러스터를 사용하는 경우 프로그램을 설계 할 때 데이터 교환 문제를 고려해야합니다. 내 자신의 접근 방식은 Redis의 세션과 유사한 모든 데이터를 저장하는 것이며, 각 스레드는 저장 및 인출 작업을 수행하며 모든 데이터는 노드 메모리에 배치되지 않습니다.
마지막으로, 클러스터는 현재 공식적으로 노드에 의한 실험으로 표시되며 API는 향후 변경 될 수 있습니다.