ABOUT ME

Today
Yesterday
Total
  • Blocking vs Non-Blocking
    프로그래밍/Node 2021. 7. 20. 13:31
    Node를 공부하면서, 중요한 개념인 이벤트 루프를 공부 해 보고자 한다.
    내가 선택한 방법은 무식하지만 그냥 node doc문서를 다 해석하는 것.

     

    Node.js에서 blocking 과 non-blocking의 차이점을 살펴보자.

    이번 개요에서 이벤트 루프 및 libuv를 참조하지만 해당 주제에 대한 사전 지식이 필요하지는 않다.

    이 글을 읽는 독자에게는 Javascript언어 및 Node.js 콜백 패턴에 대한 기본적인 이해가 있다고 가정한다.

     

    "I/O"는 주로 libuv가 지원하는 시스템의 디스크 및 네트워크와의 상호 작용을 나타낸다.

    Blocking

    Blocking은 Node.js 프로세스에서 추가적인 Javascript 실행이 non-Javascript 작업이 완료될 떄까지 기다려야 하는 경우이다. 즉, Blocking 작업이 있는 동안은, 이벤트루프가 Javascript를 실행할 수 없다.

    Node.js에서 I/O와 같이 CPU를 많이 사용하기 때문에 성능이 떨어지는 자바스크립트는 일반적으로 Blocking이라고 하지 않는다. libuv를 사용하는 Node.js 표준 라이브러리의 동기 메서드는 가장 일반적으로 사용되는 Blocking 작업이다.

    Native 모듈에도 Blocking 메서드가 있을 수 있다.  Node.js 표준 라이브러리의 모든 I/O 메서드는 비동기 버전을 제공하며, 이는 Non-Blocking이며 콜백 기능을 허용한다.  Sync로 끝나는 이름을 가진 일부 메서드는 Bloking 메서드이다.

     

    Comparing Code

    Blocking 메서드는 동기식으로 실행되고 Non-Blocking 메서드는 비동기식으로 실행된다.

     

    예를들어, File System 모듈을 사용하면, 이 모듈은 동기적으로 파일을 읽는다.

    const fs = require('fs');
    const data = fs.readFileSync('/file.md'); // blocks here until file is read

     

    다음은 이에 상응하는 비동기 예이다.

    const fs = require('fs');
    fs.readFile('/file.md', (err, data) => {
      if (err) throw err;
    });

     

    첫 번째 예제는 두 번째보다 간단해 보이지만 전체 파일을 읽을 때까지 추가 JavaScript의 실행을 Blocking한다는 단점이 있다.  동기적으로 작동할 때 에러가 발생한다면 에러를 catch할 필요가 있다. 만약 그렇지 않다면, 프로세스가 중단된다.

    비동기 버전에서 오류가 표시된 대로 발생해야 하는지 여부는 작성자의 결정에 달려있다.

     

    예제를 조금 확장 해보자.

    const fs = require('fs');
    const data = fs.readFileSync('/file.md'); // blocks here until file is read
    console.log(data);
    moreWork(); // will run after console.log

     

    다음은 비동기 예이다.

    const fs = require('fs');
    fs.readFile('/file.md', (err, data) => {
      if (err) throw err;
      console.log(data);
    });
    moreWork(); // will run before console.log

    위의 첫 번째 예에서 console.log는 moreWork()보다 먼저 호출된다. 두 번째 예에서 fs.readFile()은 Non-Blocking이므로 JavaScript를 실행을 계속할 수 있고 moreWork()가 먼저 호출된다. 즉, file을 읽을 때까지 기라지 않고, moreWork()를 실행할 수 있는 기능은 더 높은 처리량을 허용한다.

     

    Concurrency and Throughput

    Node.js에서 JavaScript는  싱글 스레드이므로 동시성은 다른 작업을 완료한 후 JavaScript 콜백 기능을 실행할 수 있는 이벤트 루프의 성능을 의미한다.

     동시 실행 방식으로 실행될 것으로 예상되는 모든 코드는 I/O와 같이 Non-JavaScript 작업이 발생할 때 이벤트 루프가 계속 실행되도록 허용해야 한다.

    예를 들어 웹 서버에 대한 각 요청을 완료하는 데 50ms가 걸리고 그 중 45ms가 비동기적으로 수행될 수 있는 데이터베이스 I/O인 경우를 생각해 보자.

    Non-Blocking 비동기 작업을 선택하면 다른 요청을 처리하기 위해 요청당 45ms를 확보할 수 있다.  Blocking 방식 대신 Non-Blocking 방식을 선택하는 것만으로도 상당한 차이가 있다.

    이벤트 루프는 동시 작업을 처리하기 위해 추가 스레드가 생성될 수 있는 다른 많은 언어의 모델과 다르다.

     

    Dangers of Mixing Blocking and Non-Blocking Code

    I/O를 다룰 때 피해야 하는 몇 가지 패턴이 있다. 예를 살펴보자.

     

    const fs = require('fs');
    fs.readFile('/file.md', (err, data) => {
      if (err) throw err;
      console.log(data);
    });
    fs.unlinkSync('/file.md');​


    위의 예에서 fs.unlinkSync()는 fs.readFile()보다 먼저 실행될 가능성이 높으며 이는 실제로 읽기 전에 file.md를 삭제한다.

    위의 로직을 작성하는 더 좋은 방법은 Non-Blocking 안에서 올바른 순서로 실행되도록 보장하는 것이다.

    const fs = require('fs');
    fs.readFile('/file.md', (readFileErr, data) => {
      if (readFileErr) throw readFileErr;
      console.log(data);
      fs.unlink('/file.md', (unlinkErr) => {
        if (unlinkErr) throw unlinkErr;
      });
    });

    위의 내용은 fs.readFile()의 콜백 내에서 fs.unlink()에 대한 Blocking 작업을 위치시킴으로써 올바른 순서를 보장한다.

     


    요약

    • javascript는 싱글스레드, 동기적인 언어....
    • 그러면 javascript는 작업을 하나씩 순차적으로만 진행해야 하나??
    • 만약 그렇다면 아무도 javascript, node를 사용하지 않을 것.
    • Non-Blocking 과 Blocking에 대한 개념
    • 이벤트루프라는 구현체를 통하여 Non-Blocking으로 다른 작업을 할 수 있다.
    • Non-Blocking과 Blocking 코드를 막 사용하면 원하는 결과를 얻지 못할 수 도 있다.
    • 따라서, 이 개념들을 이해하고, 적절하게 잘 사용해야 한다.

    참조

    https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/

     

    Overview of Blocking vs Non-Blocking | Node.js

    Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

    nodejs.org

     


    다음시간에는....

    libuv에 대해 공부해보자

    http://docs.libuv.org/en/v1.x/design.html

    '프로그래밍 > Node' 카테고리의 다른 글

    이벤트 루프?  (0) 2021.07.04
    Node.js - 비동기 중심 모델  (0) 2021.06.26
    NodeJs란  (0) 2021.05.14
    Node-passport  (0) 2021.03.10
Designed by Tistory.