이번에는 Node.js클러스터 모듈 사용에 대한 자세한 설명을 가져오겠습니다. Node.js 클러스터 모듈 사용에 대한 주의사항은 무엇인가요? , 살펴 보겠습니다.
클러스터 모듈 개요
노드 인스턴스는 단일 스레드 작업입니다. 서버 측 프로그래밍에서는 일반적으로 시스템 처리량을 향상시키기 위해 클라이언트 요청을 처리하기 위해 여러 노드 인스턴스가 생성됩니다. 이러한 다중 노드 인스턴스의 경우 이를 클러스터라고 부릅니다.
노드의 클러스터 모듈을 사용하면 개발자는 원본 프로젝트 코드를 거의 수정하지 않고도 클러스터 서비스의 이점을 얻을 수 있습니다.
클러스터에는 다음과 같은 두 가지 공통 구현 솔루션이 있으며, 노드와 함께 제공되는 클러스터 모듈은 두 번째 솔루션을 채택합니다.
옵션 1: 여러 노드 인스턴스 + 여러 포트
클러스터의 노드 인스턴스는 각각 서로 다른 포트를 수신한 다음 역방향 프록시가 여러 포트에 대한 요청 분산을 구현합니다.
장점: 구현이 간단하고 각 인스턴스가 상대적으로 독립적이므로 서비스 안정성에 좋습니다.
단점: 포트 점유 증가, 프로세스 간 통신이 더 까다롭습니다.
옵션 2: 기본 프로세스는 요청을 하위 프로세스로 전달합니다.
클러스터에서 기본 프로세스(마스터)와 여러 하위 프로세스(작업자)를 만듭니다. 마스터는 클라이언트 연결 요청을 모니터링하고 특정 정책에 따라 작업자에게 전달합니다.
장점: 일반적으로 하나의 포트만 점유되며 통신이 비교적 간단하고 전달 전략이 더 유연합니다.
단점: 구현이 상대적으로 복잡하고 주요 프로세스의 높은 안정성이 필요합니다.
시작하기 예
클러스터 모듈에서는 기본 프로세스를 마스터라고 하고 하위 프로세스를 작업자라고 합니다.
클라이언트 요청을 처리하기 위해 동일한 수의 CPU로 서버 인스턴스를 생성하는 예는 다음과 같습니다. 모두 동일한 포트에서 수신 대기하고 있습니다.
// server.js var cluster = require('cluster'); var cpuNums = require('os').cpus().length; var http = require('http'); if(cluster.isMaster){ for(var i = 0; i < cpuNums; i++){ cluster.fork(); } }else{ http.createServer(function(req, res){ res.end(`response from worker ${process.pid}`); }).listen(3000); console.log(`Worker ${process.pid} started`); }
배치 스크립트 생성: ./req.sh.
#!/bin/bash # req.sh for((i=1;i<=4;i++)); do curl http://127.0.0.1:3000 echo "" done
출력은 다음과 같습니다. 보시다시피 응답은 다양한 프로세스에서 나옵니다.
작업자 23735의 응답
작업자 23731의 응답
작업자 23729의 응답
작업자 23730의 응답
클러스터 모듈 구현 원리
클러스터 모듈을 이해합니다. 주로 3가지 질문을 이해합니다. :
어떻게 주인과 일꾼은 의사소통을 하나요?
여러 서버 인스턴스와 포트 공유를 달성하는 방법은 무엇입니까?
여러 서버 인스턴스, 클라이언트의 요청을 여러 작업자에게 배포하는 방법은 무엇입니까?
다음은 개략도를 바탕으로 소개하겠습니다. 소스코드 레벨 소개는 작성자의 github을 참고하시면 됩니다.
질문 1: 주인과 일꾼 사이의 의사소통 방법
이 질문은 비교적 간단합니다. 마스터 프로세스는 Cluster.fork()를 통해 작업자 프로세스를 생성합니다. Cluster.fork()는 child_process.fork()를 통해 내부적으로 자식 프로세스를 생성합니다.
즉,
마스터 프로세스와 작업자 프로세스는 상위 프로세스와 하위 프로세스 간의 관계입니다.
마스터 프로세스와 작업자 프로세스는 IPC 채널을 통해 통신할 수 있습니다. (중요)
질문 2: 포트 공유 구현 방법
이전 예에서 여러 워커에서 생성된 서버는 동일한 포트 3000을 수신했습니다. 일반적으로 여러 프로세스가 동일한 포트를 수신하면 시스템에서 오류를 보고합니다.
우리의 예가 왜 괜찮은가요?
비결은 Listen() 메소드가 net 모듈에서 특별히 처리된다는 것입니다. 현재 프로세스가 마스터 프로세스인지 작업자 프로세스인지에 따라:
마스터 프로세스: 이 포트에서 정상적으로 요청을 수신합니다. (특별 대우 없음)
worker进程:创建server实例。然后通过IPC通道,向master进程发送消息,让master进程也创建 server 实例,并在该端口上监听请求。当请求进来时,master进程将请求转发给worker进程的server实例。
归纳起来,就是:master进程监听特定端口,并将客户请求转发给worker进程。
如下图所示:
问题3:如何将请求分发到多个worker
每当worker进程创建server实例来监听请求,都会通过IPC通道,在master上进行注册。当客户端请求到达,master会负责将请求转发给对应的worker。
具体转发给哪个worker?这是由转发策略决定的。可以通过环境变量NODE_CLUSTER_SCHED_POLICY设置,也可以在cluster.setupMaster(options)时传入。
默认的转发策略是轮询(SCHED_RR)。
当有客户请求到达,master会轮询一遍worker列表,找到第一个空闲的worker,然后将该请求转发给该worker。
master、worker内部通信小技巧
在开发过程中,我们会通过 process.on('message', fn) 来实现进程间通信。
前面提到,master进程、worker进程在server实例的创建过程中,也是通过IPC通道进行通信的。那会不会对我们的开发造成干扰呢?比如,收到一堆其实并不需要关心的消息?
答案肯定是不会?那么是怎么做到的呢?
当发送的消息包含cmd字段,且改字段以NODE_作为前缀,则该消息会被视为内部保留的消息,不会通过message事件抛出,但可以通过监听'internalMessage'捕获。
以worker进程通知master进程创建server实例为例子。worker伪代码如下:
// woker进程 const message = { cmd: 'NODE_CLUSTER', act: 'queryServer' }; process.send(message);
master伪代码如下:
worker.process.on('internalMessage', fn);
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
위 내용은 Node.js 클러스터 모듈의 사용을 자세히 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!