경일게임아카데미 멀티 디바이스 메타버스 플랫폼 개발자 양성과정 20220914 2022/04/04~2022/12/14

Jinho Lee·2022년 9월 14일
0

2022.09.14 경일 메타버스 24주차 2일 수업내용. Node.js - 노드 기능, http 모듈 #2

노드 기능

  • 자료 : 교과서 “Node.js 교과서” ch. 3 노드 기능 알아보기 p. 89

worker_threads

  • 노드에서 멀티 스레드 방식으로 작업

  • 예시 코드 1

// 3_5_7_worker_threads.js
const {
    Worker, isMainThread, parentPort, 
} = require('worker_threads');

if(isMainThread) {      // 부모일 때
    const worker = new Worker(__filename);
    worker.on('message', message => console.log('from worker', message));
    worker.on('exit', () => console.log('worker exit'));
    worker.postMessage('ping');
} else {                // 워커일 때
    parentPort.on('message', (value) => {
        console.log('from parent', value);
        parentPort.postMessage('pong');
        parentPort.close();
    });
}
Console
> node 3_5_7_worker_threads
from parent ping
from worker pong
worker exit
  • 코드 설명

    • isMainThread : 현재 코드가 메인 스레드에서 실행되는지 워커 스레드에서 실행되는지 구분

      • 메인 스레드 : 기존에 동작하던 싱글 스레드. 부모 스레드
    • new Worker를 통해 현재 파일(__filename)을 워커 스레드에서 실행

    • 워커 생성 후 worker.postMessage로 부모에서 워커로 데이터 전송

    • 워커는 parentPore.on(’message’) 이벤트 리스너로 메시지를 받는다.

    • 워커는 parentPort.postMessage로 부모에게 메시지를 보낸다.

    • 부모는 worker.on(’message’)로 메시지를 받는다.

      • 한 번만 메시지를 받고 싶다면 once(’message’)를 사용
    • 주의 : 워커에서 on 메소드를 사용할 때는 워커를 직접 종료해야 한다.

      • parentPort.close()로 부모와의 연결 종료

      • 워커가 종료되면 부모의 worker.on(’exit’) 실행

  • 실습 코드

    • 부모와 워커에서 count를 주고받아 1씩 늘리며 출력하고 count가 3이 되면 중단
const {
    Worker, isMainThread, parentPort, 
} = require('worker_threads');

let count = 0

if(isMainThread) {      // 부모일 때
    const worker = new Worker(__filename);
    worker.on('message', message => console.log('from worker', message));
    worker.on('exit', () => {
        console.log('worker exit');
        clearInterval(interval);
    });
    const interval = setInterval(() => worker.postMessage(count++), 10);
} else {                // 워커일 때
    parentPort.on('message', (value) => {
        console.log('from parent', value);
        parentPort.postMessage(count++);
        if (count > 3)
        {
            parentPort.close();
        }
    });
}
  • 예시 코드 2

  • 예시 코드 3

  • 예시 코드 4

    • 소수의 개수를 구하는 작업

    • 워커 스레드를 사용하여 여러 개의 스레드로 문제를 나눠 푼다.

    • 상당히 어렵고 코드 양도 많아진다.

      2022. 09. 14 워커 스레드를 사용하여 소수 개수 구하기 예시 코드

    • let primes = [];

      • 코드 48번째 줄: concat 메소드로 primes 배열에 요소를 합치고, 다시 primes에 대입.
        즉, primes 변수 자체를 바꾸기에 let으로 선언
    • 멀티 스레딩에서 제일 어려운 과제 ⇒ 일을 나누기

    • 스레드를 8개 사용했더니, 약 6배 정도 빨라졌다.
      ⇒ 워커 스레드를 여덟 개 사용했다고 8배 빨라지지 않는다.

    • 스레드의 생성스레드 간 통신에서 상당한 비용이 발생

      • 이를 고려하지 않으면 멀티 스레딩이 싱글 스레딩보다 느려질 수 있다.

child_process

  • 노드에서 다른 프로그램을 실행하거나 명령어를 수행할 때 사용하는 모듈

  • 다른 언어의 코드를 실행하고 결괏값을 받을 수 있다.

  • 현재 노드 프로세스 외에 새로운 프로세스를 띄워서 명령을 수행
    → 노드 프로세스에 결과를 알려준다.

  • execspawn의 차이

    • exec : 셸 (터미널 명령어 실행 프로세스)을 실행하여 명령어 수행

    • spawn : 새로운 프로세스를 띄우며 명령어 실행

      • 세 번째 인수로 { shell: true }를 제공하면 exec처럼 셸을 실행해서 명령어 수행

기타 모듈

  • assert : 값을 비교하여 프로그램이 제대로 동작하는 지 테스트

  • dns : 도메인 이름에 대한 IP 주소 획득

  • net : HTTP보다 로우 레벨인 TCP, IPC 통신을 할 때 사용

  • string_decoder : 버퍼 데이터를 문자열로 바꿀 때 사용

  • tls : TLS, SSL 관련 작업에 사용. 보안 관련

  • tty : 터미널과 관련된 작업에 사용

  • dgram : UDP와 관련된 작업에 사용

  • v8 : V8 엔진에 직접 접근할 때 사용

  • vm : 가상 머신에 직접 접근할 때 사용

파일 시스템 접근

  • p. 138 ~ 158

  • fs 모듈

    • 기본적으로 콜백 형식 → 실무 사용을 위해 프로미스 형식으로 바꿀 수 있다.

    • readFile

      • 읽을 파일의 경로 지정 - node 명령어를 실행하는 콘솔 기준

      • 콜백 함수도 인수로 제공

      • 결과물은 버퍼 (Buffer)의 형태로 제공, 반환

        • 버퍼 (Buffer) : 단순히 설명하면 메모리의 데이터
    • writeFile

      • 생성할 파일의 경로와 내용 입력

동기 메소드와 비동기 메소드

  • 노드는 대부분의 메소드를 비동기 방식으로 처리

  • 하지만 몇몇 메소드는 동기 방식으로 사용할 수 있다.

  • 비동기 방식은 백그라운드에 요청 처리 위임 가능

    • 요청을 더 받을 수 있고, 요청 처리가 완료되면 그때 콜백 함수를 처리하면 된다.

동기와 비동기, 블로킹과 논 블로킹

  • 동기와 비동기

    • 백그라운드 작업 완료 확인 여부
  • 블로킹과 논 블로킹

    • 함수가 바로 return되는 지 여부
  • 노드에서는 동기-블로킹 방식 / 비동기-논 블로킹 방식이 대부분

    • 교차된 형식은 없다고 봐도 된다.
  • 동기-블로킹 방식

    • 백그라운드 작업 여부를 계속 확인

    • 호출한 함수가 백그라운드 작업이 끝나야 return

    • 코드가 직관적이지만 쉬는 스레드가 생겨 비효율적

  • 비동기-논 블로킹 방식

    • 호출한 함수가 바로 return되어 다음 작업으로 넘어감

    • 백그라운드 작업 여부는 신경 쓰지 않고 나중에 백그라운드 알림을 받고 처리

    • 코드는 복잡하지만 여러 요청을 동시에 처리 가능해 효율적

http 모듈로 서버 만들기

  • 자료 : 교과서 “Node.js 교과서” ch. 4 http 모듈로 서버 만들기 p. 169

  • 실제 서버 동작에 필요한 쿠키와 세션 처리, 요청 주소별 라우팅 방법

REST와 라우팅 사용

  • p. 178 ~ 189

  • 서버에 요청

    • 주소를 통해 요청의 내용을 표현

    • 서버가 이해하기 쉬운 주소가 좋다
      REST

  • REST

    • REpresentational State Transfer의 줄임말

    • 서버의 자원정의하고 자원에 대한 주소를 지정하는 방법

      • 일종의 약속

      • 서버의 자원 : 서버가 행할 수 있는 것을 통틀어 의미

    • 여기서는 기본적 개념만 빌려 사용한다.

    • 주소

      • 의미를 명확히 전달하기 위해 명사로 구성
    • HTTP 요청 메소드

      • 어떤 동작을 행할지 지시

      • GET

        • 서버 자원을 가져올 때 사용

        • 요청의 본문에 데이터를 넣지 않는다.

        • 데이터를 서버로 보내야 하면 쿼리스트링을 사용

      • POST

        • 서버에 자원을 새로 등록

        • 요청의 본문에 새로 등록할 데이터를 넣어 보낸다.

        • 표현하기 애매한 동작, 복잡한 동작은 POST를 사용

          • ex. 로그인 등
      • PUT

        • 서버의 자원을 요청에 들어있는 자원으로 치환

        • 요청의 본문에 치환할 데이터를 넣어 보낸다.

      • PATCH

        • 서버 자원의 일부만 수정

        • 요청의 본문에 일부 수정할 데이터를 넣어 보낸다.

      • DELETE

        • 서버의 자원을 삭제

        • 요청의 본문에 데이터를 넣지 않는다.

      • OPTIONS

        • 요청하기 전에 통신 옵션을 설명
    • 주소 하나가 여러 개의 요청 메소드를 가질 수 있다.

    • 장점

      • 주소와 메소드만 보고 요청의 내용을 알 수 있다.

      • GET 메소드의 경우 브라우저에서 캐싱할 수 있어 성능이 좋아진다.

  • HTTP 통신 사용 이유

    • 클라이언트와 무관하게 같은 방식으로 서버와 소통 가능

      • 서버와 클라이언트가 분리되어 있다.

      • 서버를 확장할 때 클라이언트에 구애되지 않아 좋다.

  • REST를 따르는 서버 → ‘RESTful하다’

    • 코드 작성 전, 대략적인 주소 설계를 먼저 설계하는 것이 좋다.

    • 대략적인 설계 예시

      HTTP 메소드주소역할
      GET/restFront.html 파일 제공
      GET/aboutabout.html 파일 제공
      GET/users사용자 목록 제공
      GET기타기타 정적 파일 제공
      POST/user사용자 등록
      PUT/user/사용자id해당 id의 사용자 수정
      DELETE/user/사용자id해당 id의 사용자 제거
  • 예시 코드

    • https://github.com/strange-tiger/2022_Node.js_Practice.git

    • req.method로 HTTP 요청 메소드를 구분

    • 존재하지 않는 파일을 요청했거나 올바르지 않은 (준비되지 않은) 메소드 요청인 경우
      404 NOT FOUND 에러가 응답으로 전송된다.

    • 예기치 못한 에러가 발생한 경우 500 에러가 응답으로 전송된다.

    • POSTPUT 요청의 처리에서, 요청의 본문에 들어있는 데이터를 꺼내기 위해
      req.on(’data’)req.on(’end’)를 사용

    • reqres는 내부적으로 스트림이므로 요청 / 응답의 데이터는 스트림 형식으로 전달됨

      • on 메소드에서 알 수 있듯이 이벤트 등록됨
    • 받은 데이터는 문자열이므로 JSON.parse 과정이 필요

  • res.end를 호출해도 함수는 종료되지 않는다.
    • 노드도 자바스크립트 문법을 따르므로 return을 붙이지 않는 한 함수는 종료되지 않는다.
  • 크롬에서 F12로 열 수 있는 Network 탭에서 실시간으로 보이는 네트워크 요청 내용

    • Name : 요청 주소

    • Method : 요청 메소드

    • Status : HTTP 응답 코드

    • Protocol : 통신 프로토콜

    • Type : 요청의 종류

    • xhr : AJAX 요청

    • 주의 : 데이터는 메모리에 저장되므로 서버를 종료하면 데이터가 소실된다.
      ⇒ 영구 저장은 데이터 베이스 사용

0개의 댓글