Node.js

https, http2 와 cluster

쿠와와 2020. 12. 15. 16:04

https

웹 서버에 SSL 암호화를 추가하는 모듈

  • 오고 가는 데이터를 암호화해서 중간에 다른 사람이 요청을 가로채더라도 내용을 확인할 수 없음
  • 요즘에는 https 적용이 필수(개인 정보가 있는 곳은 특히)

정보들이 탈취되는 것을 막음

 

 

http 서버를 https 서버로

  • 암호화를 위해 인증서가 필요한데 발급받아야 함

 

createServer가 인자를 두 개 받음

  • 첫 번째 인자는 인증서와 관련된 옵션 객체
  • pem, crt, key 등 인증서를 구입할 때 얻을 수 있는 파일 넣기
  • 두 번째 인자는 서버 로직

무료 SSL/TLS 인증서 : letsencrypt

const https = require('https');
const fs = require('fs');

https.createServer({
  cert: fs.readFileSync('도메인 인증서 경로'),	// 서버를 초기화 할때는 sync 써도 됨
  key: fs.readFileSync('도메인 비밀키 경로'),   // 또는 한번만 실행 할 때
  ca: [
    fs.readFileSync('상위 인증서 경로'),
    fs.readFileSync('상위 인증서 경로'),
  ],
}, (req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
  res.write('<h1>Hello Node!</h1>');
  res.end('<p>Hello Server!</p>');
})
  .listen(443, () => {
    console.log('443번 포트에서 서버 대기 중입니다!');
  });

 

http2

SSL 암호화와 더불어 최신 HTTP 프로토콜인 http/2를 사용하는 모듈

  • 요청 및 응답 방식이 기존 http/1.1보다 개선됨
  • 웹의 속도도 개선됨

 

https 모듈을 http2, createServer 메서드를 createSecureServer 메서드로

const http2 = require('http2');
const fs = require('fs');

http2.createSecureServer({
  cert: fs.readFileSync('도메인 인증서 경로'),
  key: fs.readFileSync('도메인 비밀키 경로'),
  ca: [
    fs.readFileSync('상위 인증서 경로'),
    fs.readFileSync('상위 인증서 경로'),
  ],
}, (req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
  res.write('<h1>Hello Node!</h1>');
  res.end('<p>Hello Server!</p>');
})
  .listen(443, () => {
    console.log('443번 포트에서 서버 대기 중입니다!');
  });

cluster

기본적으로 싱글 스레드인 노드가 CPU 코어를 모두 사용할 수 있게 해주는 모듈

  • 포트를 공유하는 노드 프로세스를 여러 개 둘 수 있음
  • 요청이 많이 들어왔을 때 병렬로 실행된 서버의 개수만큼 요청이 분산됨
  • 서버에 무리가 덜 감
  • 코어가 8개인 서버가 있을 때: 보통은 코어 하나만 활용
  • cluster로 코어 하나당 노드 프로세스 하나를 배정 가능
  • 성능이 8배가 되는 것은 아니지만 개선됨
  • 단점: 컴퓨터 자원(메모리, 세션 등) 공유 못 함
  • Redis 등 별도 서버로 해결

서버 클러스터링

 

마스터 프로세스와 워커 프로세스

  • 마스터 프로세스는 CPU 개수만큼 워커 프로세스를 만듦(worker_threads랑 구조 비슷)
  • 요청이 들어오면 워커 프로세스에 고르게 분배

하나의 포트에 여러가지 서버를 띄울 수 있음

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

if (cluster.isMaster) {
  console.log(`마스터 프로세스 아이디: ${process.pid}`);
  // CPU 개수만큼 워커를 생산
  for (let i = 0; i < numCPUs; i += 1) {
    cluster.fork();
  }
  // 워커가 종료되었을 때
  cluster.on('exit', (worker, code, signal) => {
    console.log(`${worker.process.pid}번 워커가 종료되었습니다.`);
    console.log('code', code, 'signal', signal);
    cluster.fork();
  });
} else {
  // 워커들이 포트에서 대기
  http.createServer((req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
    res.write('<h1>Hello Node!</h1>');
    res.end('<p>Hello Cluster!</p>');
    setTimeout(() => { // 워커 존재를 확인하기 위해 1초마다 강제 종료
      process.exit(1);
    }, 1000);
  }).listen(8086);

  console.log(`${process.pid}번 워커 실행`);
}

 

'Node.js' 카테고리의 다른 글

node_modules, SemVer 버저닝  (0) 2020.12.17
npm, package.json 패키지 관리  (0) 2020.12.16
쿠키, 세션 이해하기  (0) 2020.12.14
REST API와 라우팅  (0) 2020.12.14
서버와 클라이언트  (0) 2020.12.13