Nodejs 프로 세 스 간 통신
Node 는 단일 스 레 드 에서 실행 되 지만 다 중 핵 / 다 중 컴퓨터 에서 다 중 프로 세 스 의 장점 을 이용 할 수 없다 는 것 은 아 닙 니 다.
사실 Node 는 처음에 디자인 에서 분포 식 네트워크 장면 을 고려 했다.
Node is a single-threaded, single-process system which enforces shared-nothing design with OS process boundaries. It has rather good libraries for networking. I believe this to be a basis for designing very large distributed programs. The “nodes” need to be organized: given a communication protocol, told how to connect to each other. In the next couple months we are working on libraries for Node that allow these networks.
P. S. Node 가 Node 라 는 이유 에 대해 서 만 나 보 세 요. Why is Node.js named Node.js?
2. 프로 세 스 만 들 기
통신 방식 은 프로 세 스 생 성 방식 과 관련 이 있 으 며, Node 는 프로 세 스 를 만 드 는 4 가지 방식 이 있 습 니 다.
spawn()
, exec()
, execFile()
와 fork()
spawn
const { spawn } = require('child_process'); const child = spawn('pwd'); // // const child = spawn('find', ['.', '-type', 'f']);
spawn()
돌아 가기 ChildProcess
실례, ChildProcess
역시 이벤트 메커니즘 (EventEmitter API) 을 바탕 으로 일부 이 벤트 를 제공 했다.exit
: 하위 프로 세 스 가 종료 되 었 을 때 터치 하면 프로 세 스 가 종료 되 었 음 을 알 수 있 습 니 다 ( code
와 signal
) disconnect
: 부모 프로 세 스 호출 child.disconnect()
시 촉발 error
: 하위 프로 세 스 생 성 에 실 패 했 거나, kill
시 촉발 close
: 하위 프로 세 스 의 stdio
흐름 (표준 입 출력 흐름) 종료 시 터치 message
: 하위 프로 세 스 통과 process.send()
메 시 지 를 보 낼 때 터치 합 니 다. 부자 프로 세 스 간 에 이 를 통 해 내 장 된 메시지 메커니즘 통신 child.stdin
, child.stdout
와 child.stderr
하위 프로 세 스에 접근 하 는 stdio
흐름, 이 흐름 이 닫 혔 을 때 하위 프로 세 스 가 실 행 됩 니 다. close
사건P.S.
close
과 exit
의 차 이 는 주로 다 중 프로 세 스 가 같은 것 을 공유 하 는 데 나타난다. stdio
흐 르 는 장면 에서 어떤 프로 세 스 가 종료 되 었 다 는 것 은 의미 하지 않 습 니 다. stdio
흐름 이 닫 혔 습 니 다.하위 프로 세 스 중,
stdout/stderr
읽 기 가능 한 특성 을 가지 고 있 으 며, stdin
Writable 특성 을 가지 고 있 습 니 다. 주 프로 세 스 의 상황 과 정반 대 입 니 다. : child.stdout.on('data', (data) => { console.log(`child stdout:
${data}`); }); child.stderr.on('data', (data) => { console.error(`child stderr:
${data}`); });
프로 세 스 이용
stdio
흐름 의 파이프 특성 은 더욱 복잡 한 일 을 완성 할 수 있다. 예 를 들 어:const { spawn } = require('child_process'); const find = spawn('find', ['.', '-type', 'f']); const wc = spawn('wc', ['-l']); find.stdout.pipe(wc.stdin); wc.stdout.on('data', (data) => { console.log(`Number of files ${data}`); });
작용
find . -type f | wc -l
현재 디 렉 터 리 파일 의 수량 을 재 귀적 으로 통계 합 니 다.IPC 옵션
그리고
spawn()
방법의 stdio
옵션 을 사용 하면 IPC 체 제 를 구축 할 수 있 습 니 다.const { spawn } = require('child_process'); const child = spawn('node', ['./ipc-child.js'], { stdio: [null, null, null, 'ipc'] }); child.on('message', (m) => { console.log(m); }); child.send('Here Here'); // ./ipc-child.js process.on('message', (m) => { process.send(`< ${m}`); process.send('> x3'); });
... 에 대하 여
spawn()
IPC 옵션 에 대한 자세 한 정 보 는 보 세 요. options.stdio exec
spawn()
방법 은 기본적으로 셸 을 만 들 지 않 고 들 어 오 는 명령 을 수행 합 니 다 (그래서) 성능 이 좀 좋아요. ),그리고 exec()
방법 은 셸 을 만 듭 니 다. 또한, exec()
stream 기반 이 아니 라 명령 에 들 어 온 실행 결 과 를 buffer 에 잠시 저장 하고 전체 반전 함수 에 전달 합 니 다.exec()
방법의 특징 은 셸 문법 완전 지원 ,임의의 셸 스 크 립 트 를 직접 전송 할 수 있 습 니 다. 예 를 들 어:const { exec } = require('child_process'); exec('find . -type f | wc -l', (err, stdout, stderr) => { if (err) { console.error(`exec error: ${err}`); return; } console.log(`Number of files ${stdout}`); });
그러나.
exec()
방법 도 이 로 인해 존재 한다. 명령 주입 의 안전 위험 은 사용자 입력 등 동적 내용 을 포함 하 는 장면 에서 특히 주의해 야 한다. 따라서 exec()
방법의 적용 장면 은 셸 문법 을 직접 사용 하고 예상 출력 데 이 터 량 이 많 지 않 기 를 바 랍 니 다 (메모리 압력 이 존재 하지 않 습 니 다).그렇다면 셸 문법 도 지원 하고 stream IO 장점 도 가 진 방식 이 있 습 니까?
있다 쌍방 이 모두 좋게 하 는 방식 다음 과 같다.
const { spawn } = require('child_process'); const child = spawn('find . -type f | wc -l', { shell: true }); child.stdout.pipe(process.stdout);
열다
spawn()
의 shell
옵션 을 선택 하고 통과 pipe()
명령 실행 결 과 를 볼 수 있 도록 하위 프로 세 스 의 표준 출력 을 현재 프로 세 스 의 표준 입력 에 간단하게 받 습 니 다. 실제로 더 쉬 운 방법 이 있 습 니 다.const { spawn } = require('child_process'); process.stdout.on('data', (data) => { console.log(data); }); const child = spawn('find . -type f | wc -l', { shell: true, stdio: 'inherit' });
stdio: 'inherit'
하위 프로 세 스 가 현재 프로 세 스 의 표준 입 출력 을 계승 할 수 있 도록 합 니 다 (공유) stdin
, stdout
와 stderr
따라서 상례 로 현재 프로 세 스 를 감청 할 수 있 습 니 다. process.stdout
의 data
이벤트 가 하위 프로 세 스 의 출력 결 과 를 가 져 옵 니 다.이외에
stdio
와 shell
옵션, spawn()
다음 과 같은 다른 옵션 도 지원 합 니 다.const child = spawn('find . -type f | wc -l', { stdio: 'inherit', shell: true, // , process.env env: { HOME: '/tmp/xxx' }, // cwd: '/tmp', // detached: true });
주의 하 다. ,
env
옵션 은 환경 변수 형식 으로 하위 프로 세 스에 데 이 터 를 전달 하 는 것 외 에 샌 드 박스 식 환경 변수 격 리 를 실현 할 수 있 습 니 다. 기본 값 으로 process.env
하위 프로 세 스 의 환경 변수 집합 으로 하위 프로 세 스 는 현재 프로 세 스 와 마찬가지 로 모든 환경 변 수 를 방문 할 수 있 습 니 다. 상기 에서 사용자 정의 대상 을 하위 프로 세 스 의 환경 변수 집합 으로 지정 하면 하위 프로 세 스 는 다른 환경 변 수 를 방문 할 수 없습니다.따라서 환경 변 수 를 증가 / 삭제 하려 면 이렇게 해 야 합 니 다.
var spawn_env = JSON.parse(JSON.stringify(process.env)); // remove those env vars delete spawn_env.ATOM_SHELL_INTERNAL_RUN_AS_NODE; delete spawn_env.ELECTRON_RUN_AS_NODE; var sp = spawn(command, ['.'], {cwd: cwd, env: spawn_env});
detached
옵션 이 더 재 미 있 습 니 다.const { spawn } = require('child_process'); const child = spawn('node', ['stuff.js'], { detached: true, stdio: 'ignore' }); child.unref();
이러한 방식 으로 만 든 독립 프로 세 스 행 위 는 운영 체제 에 달 려 있 습 니 다. Windows 에서 detached 하위 프로 세 스 는 자신의 console 창 을 가지 고 있 으 며 Linux 에 서 는 이 프로 세 스 가 새 프로 세 스 그룹 만 들 기 (이 기능 은 하위 프로 세 스 족 을 관리 하 는 데 사용 할 수 있 습 니 다. tree-kill 매 직
unref()
방법 은 관 계 를 끊 는 데 사 용 됩 니 다. "부모" 프로 세 스 는 독립 적 으로 종료 할 수 있 습 니 다. (하위 프로 세 스 가 따라 종료 되 지 않 습 니 다) 그러나 이 때 하위 프로 세 스 를 주의해 야 합 니 다. stdio
'부모' 프로 세 스 에 독립 해 야 합 니 다. 그렇지 않 으 면 '부모' 프로 세 스 가 종 료 된 후에 도 하위 프로 세 스 가 영향 을 받 을 수 있 습 니 다.execFile
const { execFile } = require('child_process'); const child = execFile('node', ['--version'], (error, stdout, stderr) => { if (error) { throw error; } console.log(stdout); });
... 과
exec()
방법 은 유사 하지만 셸 을 통 해 실행 되 지 않 습 니 다 (그래서 성능 이 조금 좋 습 니 다). 그래서 전송 을 요구 합 니 다. 실행 파일 。Windows 의 일부 파일 은 직접 실행 할 수 없습니다. 예 를 들 어 .bat
와 .cmd
이 서류 들 은 사용 할 수 없습니다. execFile()
집행 은 빌 릴 수 밖 에 없다. exec()
또는 오픈 shell
옵션 의 spawn()
P. S. 와
exec()
똑 같 아 요. stream 기반 이 아 닙 니 다. ,출력 데이터 양 위험 도 존재 합 니 다.xxxSync
spawn
, exec
와 execFile
하위 프로 세 스 가 종 료 될 때 까지 대응 하 는 동기 화 차단 버 전이 있 습 니 다.const {
spawnSync, execSync, execFileSync, } = require('child_process');
동기 화 방법 은 스 크 립 트 작업 을 간소화 하 는 데 사 용 됩 니 다. 예 를 들 어 시작 프로 세 스, 다른 때 는 이러한 방법 을 피해 야 합 니 다.
fork
fork()
네. spawn()
의 변 체 는 Node 프로 세 스 를 만 드 는 데 사 용 됩 니 다. 가장 큰 특징 은 부자 프로 세 스 자체 통신 체제 (IPC 파이프) 입 니 다.The child_process.fork() method is a special case of child_process.spawn() used specifically to spawn new Node.js processes. Like child_process.spawn(), a ChildProcess object is returned. The returned ChildProcess will have an additional communication channel built-in that allows messages to be passed back and forth between the parent and child. See subprocess.send() for details.
예 를 들 면:
var n = child_process.fork('./child.js'); n.on('message', function(m) { console.log('PARENT got message:', m); }); n.send({ hello: 'world' }); // ./child.js process.on('message', function(m) { console.log('CHILD got message:', m); }); process.send({ foo: 'bar' });
... 때문에
fork()
자체 통신 체제 의 장점 은 특히 시간 소모 논 리 를 분리 하 는 데 적합 하 다. 예 를 들 어:const http = require('http'); const longComputation = () => { let sum = 0; for (let i = 0; i < 1e9; i++) { sum += i; }; return sum; }; const server = http.createServer(); server.on('request', (req, res) => { if (req.url === '/compute') { const sum = longComputation(); return res.end(`Sum is ${sum}`); } else { res.end('Ok') } }); server.listen(3000);
이렇게 하 는 치 명 적 인 문 제 는 누군가가 방문 하면
/compute
후속 요청 은 제때에 처리 할 수 없습니다. 이벤트 순환 이 아직 longComputation
시간 계산 이 끝 날 때 까지 막 혀 있어 야 서비스 능력 을 회복 할 수 있다.주 프로 세 스 의 이벤트 순환 을 막 는 데 시간 이 걸 리 지 않도록
longComputation()
하위 프로 세 스 로 나 누 기:// compute.js
const longComputation = () => { let sum = 0; for (let i = 0; i < 1e9; i++) { sum += i; }; return sum; }; // , process.on('message', (msg) => { const sum = longComputation(); process.send(sum); });
주 프로 세 스 하위 프로 세 스 실행 열기
longComputation
: const http = require('http'); const { fork } = require('child_process'); const server = http.createServer(); server.on('request', (req, res) => { if (req.url === '/compute') { const compute = fork('compute.js'); compute.send('start'); compute.on('message', sum => { res.end(`Sum is ${sum}`); }); } else { res.end('Ok') } }); server.listen(3000);
주 프로 세 스 의 이벤트 순환 은 더 이상 시간 계산 에 의 해 막 히 지 않 지만 프로 세 스 의 수량 은 더 제한 되 어야 합 니 다. 그렇지 않 으 면 자원 이 프로 세 스 에 의 해 소 모 될 때 서비스 능력 이 영향 을 받 을 수 있 습 니 다.
P. S. 실제로,
cluster
모듈 은 다 중 프로 세 스 서비스 능력 에 대한 패키지 입 니 다. 사고방식 은 이 간단 한 예시 와 유사 하 다통신 방식
1. stdin / stdout 을 통 해 json 전달
stdin/stdout and a JSON payload
가장 직접적인 통신 방식 으로 하위 프로 세 스 의 handle 를 가 져 오 면 접근 할 수 있 습 니 다.
stdio
흐름 message
형식 으로 즐 거 운 통신 을 시작 합 니 다.const { spawn } = require('child_process'); child = spawn('node', ['./stdio-child.js']); child.stdout.setEncoding('utf8'); // - child.stdin.write(JSON.stringify({ type: 'handshake', payload: ' ' })); // - child.stdout.on('data', function (chunk) { let data = chunk.toString(); let message = JSON.parse(data); console.log(`${message.type} ${message.payload}`); });
하위 프로 세 스 와 유사:
// ./stdio-child.js
// -
process.stdin.on('data', (chunk) => { let data = chunk.toString(); let message = JSON.parse(data); switch (message.type) { case 'handshake': // - process.stdout.write(JSON.stringify({ type: 'message', payload: message.payload + ' : hoho' })); break; default: break; } });
P. S. VS 코드 프로 세 스 간 통신 은 이런 방식 을 채택 했다. 구체 적 으로 보면 access electron API from vscode extension
뚜렷 하 다 제한 하 다. '하위' 프로 세 스 를 가 져 와 야 하 는 handle 입 니 다. 두 개의 완전히 독립 된 프로 세 스 간 에 이런 방식 으로 통신 할 수 없습니다 (예 를 들 어 크로스 응용, 심지어 기 계 를 뛰 어 넘 는 장면)
P. S. stream 및 pipe 에 대한 자세 한 정 보 는 보 세 요. Node 의 흐름
2. 원생 IPC 지원
... 와 같다
spawn()
및 fork()
의 예 를 들 어 프로 세 스 간 에 내 장 된 IPC 메커니즘 을 통 해 통신 할 수 있다.부모 프로 세 스:
process.on('message')
받 음 child.send()
발 process.on('message')
받 음 process.send()
발 3.sockets
네트워크 를 통 해 프로 세 스 간 통신 을 완성 합 니 다. 프로 세 스 를 뛰 어 넘 을 수 있 을 뿐만 아니 라 기계 도 뛰 어 넘 을 수 있다.
node-ipc 이런 방안 을 채택 하 다. 예 를 들 면:
// server
const ipc=require('../../../node-ipc'); ipc.config.id = 'world'; ipc.config.retry= 1500; ipc.config.maxConnections=1; ipc.serveNet( function(){ ipc.server.on( 'message', function(data,socket){ ipc.log('got a message : ', data); ipc.server.emit( socket, 'message', data+' world!' ); } ); ipc.server.on( 'socket.disconnected', function(data,socket){ console.log('DISCONNECTED
',arguments); } ); } ); ipc.server.on( 'error', function(err){ ipc.log('Got an ERROR!',err); } ); ipc.server.start(); // client const ipc=require('node-ipc'); ipc.config.id = 'hello'; ipc.config.retry= 1500; ipc.connectToNet( 'world', function(){ ipc.of.world.on( 'connect', function(){ ipc.log('## connected to world ##', ipc.config.delay); ipc.of.world.emit( 'message', 'hello' ); } ); ipc.of.world.on( 'disconnect'
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.