논블로킹 I/O

이동영·2026년 2월 15일

웹개발

목록 보기
35/36

Java(Spring MVC)에서는 DB 조회나 파일 읽기 요청을 보내면, 결과가 돌아올 때까지 해당 스레드는 아무것도 못 하고 대기한다. 이를 Blocking I/O라고 한다. 반면 Node.js는 작업을 던져두고 즉시 다음 코드를 실행한다. 이것이 바로 Non-blocking I/O다.

1. Blocking vs Non-blocking: '점원'의 차이

  • Java (Blocking) : 카페 점원이 주문을 받고, 커피가 나올 때까지 진동벨도 안 주고 손님 앞에 서서 기다리는 격이다. 뒤에 온 손님들은 앞 손님의 커피가 나올 때까지 주문조차 못 한다. (그래서 Java는 점원(Thread)을 늘리는 방식으로 해결한다.)
  • Node.js (Non-blocking) : 점원이 주문을 받자마자 진동벨(Callback)을 주고 "다음 손님 오세요!"라고 외친다. 커피는 주방(Background)에서 따로 만들어지고, 점원은 그동안 수십 명의 주문을 더 받는다.

2. Node.js가 I/O를 처리하는 방식 (Libuv의 역할)

Node.js 자체는 싱글 스레드지만, I/O 작업은 OS 커널이나 Libuv의 스레드 풀에 위임한다.

  1. Request : 사용자가 파일을 다운로드 요청한다.
  2. Offload : 메인 스레드는 파일 시스템(FS)에 "파일 읽어줘"라고 명령을 던지고, 본인은 다음 루프로 넘어간다.
  3. Wait (Background) : 실제 파일을 읽는 무거운 작업은 OS나 Libuv 스레드 풀이 담당한다. 메인 스레드는 자유롭다.
  4. Callback : 파일 읽기가 끝나면 이벤트 루프의 Task Queue에 "완료!"라는 신호와 함께 콜백 함수가 들어온다.
  5. Response : 메인 스레드가 한가할 때 해당 콜백을 실행하여 사용자에게 파일을 전송한다.

3. Java 코드 vs Node.js 코드 비교

Java (Blocking)

// 이 라인에서 DB 응답이 올 때까지 스레드가 멈춘다(Block).
Script script = repository.findById(id); 
System.out.println(script.getTitle());

Node.js (Non-blocking)

// DB 조회를 던져놓고 바로 아래 console.log를 실행한다.
db.scripts.findOne({ id }, (err, script) => {
    // 나중에 응답이 오면 실행될 콜백
    console.log("2. DB 결과 출력:", script.title);
});
console.log("1. 다음 로직 실행 중...");

// 출력 순서: 1 -> 2

4. JavaScript에서 블로킹과 논블로킹 사용법

블로킹

function longRunningTask() {
  // 오래 걸리는 작업
  console.log('작업 끝');
}

console.log('시작');
longRunningTask();

console.log('다음 작업');

결과는 다음과 같다.

시작
작업 끝
다음 작업

논블로킹

function longRunningTask() {
  // 오래 걸리는 작업
  console.log('작업 끝');
}
console.log('시작');
setTimeout(longRunningTask, 0);
console.log('다음 작업');

결과는 다음과 같다.

시작
다음 작업
작업 끝

이렇게 setTimeout(콜백, 0)은 코드를 논블로킹으로 만들기 위해 사용하는 기법 중 하나이다. 사실 노드에서는 setTimeout(콜백, 0) 대신 setImmediate 방식을 사용하긴 한다. 자세한 내용은 나중에 포스트에서 따로 다루겠다.

4. 왜 논블로킹이 스타트업에 유리한가?

  • 동시 접속 처리량 : Java는 접속자가 늘어나면 스레드도 늘어나며 메모리 소모(C10K 문제)가 극심해진다. Node.js는 단 하나의 스레드로 수천 개의 I/O 요청을 '진동벨' 방식으로 관리하므로 메모리 효율이 압도적이다.
  • 확장성 : 드라마켓 초기 모델처럼 저사양 서버(AWS t3.micro 등)에서도 수많은 동시 조회를 매끄럽게 처리할 수 있다.

5. 주의사항 : "CPU 집약적 작업은 논외"

논블로킹은 I/O(네트워크, 파일, DB)에만 해당한다. 만약 메인 스레드에서 복잡한 암호화 알고리즘을 돌리거나 대용량 이미지 픽셀을 직접 계산한다면, 그것은 '블로킹' 작업이 되어 서버 전체를 멈추게 한다.

I/O 작업은 비동기로 넘기되, 무거운 연산은 별도의 Worker Thread나 마이크로서비스로 분리하는 것이 Node.js 아키텍처의 핵심이다.

0개의 댓글