AI + Career

✅ Node.js가 싱글스레드임에도 불구하고 비동기 처리를 통해 빠른 이유는?

octo54 2025. 5. 26. 10:22
반응형

 

✅ Node.js가 싱글스레드임에도 불구하고 비동기 처리를 통해 빠른 이유는?

Node.js는 자바스크립트를 기반으로 한 서버 사이드 런타임으로, 싱글 스레드(single-threaded) 아키텍처를 채택하고 있습니다.
하지만 놀랍게도 Node.js는 고성능 비동기 I/O 처리를 통해 높은 처리량을 자랑합니다.
이번 글에서는 Node.js가 싱글 스레드 구조임에도 빠른 이유, 그리고 그 핵심인 이벤트 루프와 비동기 처리 모델을 상세히 설명합니다.


📌 1. Node.js의 싱글 스레드 구조란?

Node.js는 기본적으로 하나의 메인 스레드에서 모든 JavaScript 코드를 실행합니다.
이는 웹 브라우저의 JavaScript 엔진(V8)과 같은 방식이며, 동시성(concurrency) 문제를 단순하게 만들어줍니다.

그러나 I/O 작업 (예: 파일 읽기, DB 요청, 네트워크 통신 등)은 멀티스레드 기반의 libuv 라이브러리에서 처리됩니다.


📌 2. 핵심: 이벤트 루프(Event Loop)

Node.js의 핵심은 **이벤트 루프(Event Loop)**입니다.
이는 메인 스레드에서 **작업 큐(Task Queue)**를 감시하고,
비동기 작업의 완료 이벤트를 순차적으로 처리하는 구조입니다.

🔄 이벤트 루프 동작 순서

  1. JS 코드 실행 (동기 작업)
  2. 비동기 작업 등록 (예: fs.readFile, setTimeout, HTTP 요청)
  3. 비동기 작업 완료 → 콜백 큐에 추가
  4. 이벤트 루프가 메인 스레드가 idle 상태가 되면 큐에서 콜백 실행

📌 3. 비동기 I/O 처리 방식

Node.js의 빠른 처리의 핵심은 **"I/O 작업을 블로킹하지 않는 구조"**입니다.

✅ 일반적인 동기 방식 (블로킹)

const data = fs.readFileSync('file.txt');
console.log(data.toString());
  • 파일을 다 읽을 때까지 다음 줄 실행 안 됨

✅ Node.js 비동기 방식 (논블로킹)

반응형
fs.readFile('file.txt', (err, data) => {
  if (err) throw err;
  console.log(data.toString());
});
console.log('파일 읽는 중...');
  • 파일 읽는 동안 다음 코드 실행 → 처리량 증가

📌 4. libuv와 Thread Pool

Node.js 내부에는 libuv라는 C 기반의 라이브러리가 존재하며,
I/O 처리를 위한 **Thread Pool(기본 4개)**을 통해 실제 작업을 분산시킵니다.

작업 종류 처리 방식

파일 시스템, DNS, 압축 libuv Thread Pool 사용
네트워크 요청 (HTTP 등) OS 비동기 이벤트 처리 (epoll, IOCP 등)

📌 5. 싱글 스레드의 장점

장점 설명

경쟁 조건(Race Condition) 없음 메인 스레드 하나로 작동하기 때문에 동시 접근 문제 ↓
Lock-free 구조 쓰레드 락, 세마포어 등 복잡한 동기화 필요 없음
직관적인 디버깅 흐름이 직선적이며, 상태 관리가 쉬움

📌 6. 실무에서 겪은 성능 문제와 해결

🧪 문제

  • 이미지 압축, 대용량 파일 처리 등 CPU 바운드 작업에서 Node.js가 이벤트 루프를 블로킹하며 전체 성능 저하

✅ 해결

  • Worker Threads, 또는 child_process 모듈을 사용하여 CPU 집중 작업을 메인 스레드에서 분리
const { Worker } = require('worker_threads');

new Worker('./heavy-task.js');

또는 **작업을 큐에 넣고 외부 서버에서 처리하는 아키텍처(Microservice + Message Queue)**로 분산 처리


📌 7. 면접에서 이렇게 답하세요

Node.js는 싱글 스레드 기반이지만, 이벤트 루프와 libuv를 기반으로 비동기 I/O를 처리하여 높은 처리량을 자랑합니다.
CPU 작업이 아닌, 네트워크 요청, 파일 시스템 접근 등 I/O 위주의 서버에 적합하며,
실무에서는 이벤트 루프 블로킹을 피하기 위해 비동기 처리 방식, 또는 Worker Threads를 적절히 활용합니다.



Node.js,이벤트루프,비동기처리,싱글스레드,libuv,ThreadPool,논블로킹IO,WorkerThreads,백엔드성능,프론트엔드면접