[Node.js] Node.js의 비동기 처리 모델 이해하기

artp·2025년 4월 19일

node.js

목록 보기
2/9
post-thumbnail

Node.js의 비동기 처리 모델

Node.js는 단일 스레드로 동작하지만, 동시에 수많은 요청을 빠르게 처리할 수 있는 고성능 서버로 잘 알려져 있습니다.
그 비결은 바로 비동기 이벤트 기반 처리 모델, 즉 이벤트 루프(Event Loop)라는 독특한 구조에 있습니다.

비동기 이벤트 기반 처리 모델은 Node.js가 “이벤트 루프를 통해, 논블로킹 방식으로, 하나의 스레드만으로도 수많은 클라이언트 요청을 효율적으로 처리하는 구조”를 의미합니다.

동기(Synchronous) vs 비동기(Asynchronous)

동기 방식은 작업을 하나씩 순서대로 처리하는 방식입니다.
앞선 작업이 끝나야만 다음 작업을 시작할 수 있기 때문에, 중간에 느린 작업이 있으면 전체 흐름이 지연됩니다(=블로킹).

반면, 비동기 방식은 여러 작업을 동시에 병행할 수 있는 방식입니다.
어떤 작업이 진행되는 동안 다른 작업이 기다리지 않고 계속 처리되며, 각 작업의 결과는 이벤트나 콜백 함수를 통해 나중에 받아 처리됩니다(=논블로킹).

비유 예시

  • 동기 처리: 냄비에 물을 끓이는 동안 가만히 서서 물이 끓기를 기다린 다음, 끓고 나서 야채를 썰고 넣음
  • 비동기 처리: 물을 끓이기 시작한 뒤 타이머(이벤트)를 설정해두고, 그동안 야채를 썰거나 다른 준비를 함.
    물이 끓으면 타이머가 울리고, 등록해둔 콜백(“야채 넣는 함수”)이 실행되어 요리가 이어짐

이처럼 비동기 처리 방식은 기다리는 시간 동안 다른 작업을 수행할 수 있도록 해줍니다.

Node.js는 어떻게 하나의 스레드로 많은 요청을 처리할까?

Node.js는 이벤트 루프(Event Loop)라는 구조를 통해 단일 스레드로도 많은 요청을 동시에 처리합니다. 시간이 오래 걸리는 작업(예: DB 조회, 파일 읽기 등)은 백그라운드(운영체제나 스레드 풀 등)에 맡기고, 메인 스레드는 다른 요청을 계속 처리합니다.
이러한 구조 덕분에 서버는 I/O 작업(예: 파일 읽기, DB 접근 등)에 소요되는 시간 동안에도 멈추지 않고 다른 작업을 계속해서 처리할 수 있습니다.

Node.js의 이벤트 루프는 끊임없이 돌아가면서 이벤트 큐를 확인하고, 완료된 작업이나 새로운 요청이 생기면 해당 콜백 함수를 호출하여 처리합니다.

예를 들어 Node.js 서버에 여러 클라이언트 요청이 들어오면, 이벤트 루프는 각 요청을 차례로 받아들이면서 데이터베이스 조회 같은 작업은 비동기적으로 시작만 해두고 바로 다음 요청을 처리합니다. 나중에 데이터베이스 조회가 완료되면 그 완료 이벤트를 감지하여 미리 등록된 콜백(후속 처리 함수)을 실행하는 식입니다.

이렇게 하면 하나의 스레드로도 동시에 수많은 클라이언트를 상대할 수 있게 됩니다. 실제로 Node.js는 단일 스레드와 논블로킹 I/O를 통해, 수만에서 수십만 개의 동시 연결도 무리 없이 처리할 수 있는 확장성을 가지고 있습니다.

흐름 요약

  • 요청이 들어오면 처리 시작
  • 시간이 오래 걸리는 작업은 백그라운드로 위임
  • 메인 스레드는 다음 요청 처리
  • 백그라운드 작업이 완료되면 이벤트 큐에 등록
  • 이벤트 루프가 큐에서 꺼내 콜백 함수 실행

결과적으로 하나의 스레드로도 마치 여러 작업이 동시에 처리되는 것처럼 효율을 낼 수 있습니다.

비유: 레스토랑

  • 동기 방식: 웨이터가 A 테이블에 주문을 받고 주방에서 요리 나올 때까지 기다렸다가 서빙한 후, B 테이블로 이동
  • 비동기 방식: A 테이블 주문을 받고 주방에 맡긴 뒤 바로 B 테이블 주문을 받음. 요리가 완성되면 주방에서 벨을 눌러 알리고 그때 A 테이블로 가서 서빙

즉, Node.js의 메인 스레드는 "요리 완료 신호(이벤트)"를 기다리지 않고 다른 손님의 주문을 계속 처리합니다. 하나의 웨이터(스레드)로도 많은 테이블(요청)을 효율적으로 처리하는 구조입니다.

Node.js 서버가 왜 비용 효율적이고 고성능인가?

기존의 멀티스레드 서버요청마다 별도 스레드를 만들거나 할당하는데, 스레드가 많아지면 각 스레드마다 별도의 메모리(스택 공간)가 필요하고 CPU가 스레드들을 전환(context switch)하느라 부하가 걸립니다.

반면 Node.js 서버는 스레드 하나로 일을 처리하므로 여러 개의 스레드가 차지하는 메모리를 절약하고, 스레드 간 전환에 따르는 추가 CPU 비용도 최소화합니다. 불필요한 대기나 중복 작업이 줄어드니 그만큼 한정된 자원으로 더 많은 요청을 처리할 수 있게 됩니다

Node.js는 스레드를 새로 만들지 않고도 요청을 처리하기 때문에

  • 메모리를 적게 사용하고
  • CPU 자원을 효율적으로 사용하며
  • 스레드 관리 비용이 줄어듭니다.

결과적으로 적은 자원으로도 많은 요청을 동시에 처리할 수 있어 비용 효율적인 고성능 서버를 구축할 수 있는 것입니다.

정리

항목설명
구조이벤트 루프 + 논블로킹 I/O 기반의 비동기 처리
장점단일 스레드로도 대규모 동시 처리 가능
비유웨이터가 신호 받고 테이블 이동하며 여러 손님 처리하는 방식
효과메모리 절약, CPU 효율, 비용 절감, 확장성 확보
용어 설명Non-blocking = 기다리지 않음, Event loop = 이벤트를 감지하며 루프
profile
donggyun_ee

0개의 댓글