Node.js의 이벤트 루프와 싱글톤 패턴의 안전한 사용 방법
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
개발 툴
대상자
- *Node.js 개발자**
- 난이도: 중간*
- Node.js의 비동기 처리와 싱글톤 패턴의 안전한 사용법을 이해하고자 하는 개발자에게 유용*
핵심 요약
- Node.js는 비동기 처리를 통해 단일 스레드로도 고并发 처리 가능
- 싱글톤 패턴은
read-only
,in-memory
연산 시 안전하지만,blocking I/O
또는shared mutable state
사용 시 위험 AsyncLogger
와AsyncLocalStorage
를 활용한 비동기 처리 및 컨텍스트 고립이 안정성 향상에 기여
섹션별 세부 요약
1. Node.js 이벤트 루프 메커니즘
- 단일 스레드로 비동기 작업을 처리
- libuv
라이브러리로 디스크 I/O, 네트워크 요청 등 시간 소요 작업을 백그라운드 스레드에 위임
- 비동기 작업 처리 흐름
- 요청 수신 → 2. 비동기 작업 위임 → 3. 이벤트 루프 계속 실행 → 4. 완료 시 콜백 큐에 추가 → 5. 이벤트 루프가 실행
- 비동기 처리로 인해 수백만 개 요청 동시 처리 가능
2. 싱글톤 패턴의 안전한 사용 예시
Config
클래스 예시
- read-only
연산, 메모리 내 데이터 접근, I/O 없음 → 100만 개 요청 처리 시에도 안전
- 코드: class Config { constructor() { this.settings = { dbHost: 'localhost' }; } get(key) { return this.settings[key]; } }
- Express 서버 예시
- config.get('dbHost')
호출 시 이벤트 루프 차단 없이 빠른 응답 제공
3. 싱글톤 패턴의 위험한 사용 사례
- _a) Blocking I/O Operations_
- fs.createWriteStream
사용 시 파일 쓰기로 인해 이벤트 루프 차단
- 예시: this.logFile.write(...)
- _b) Shared Mutable State_
- setRecipients()
동시 호출 시 race condition
발생
- 예시: this.recipients = list;
4. 안전한 싱글톤 패턴 구현 방법
- _a) Async Logging with Batching_
- 로그 메시지 큐잉 → 배치 처리 → setImmediate()
로 이벤트 루프 양보
- 코드: await fs.promises.appendFile(...); await new Promise(resolve => setImmediate(resolve));
- _b) AsyncLocalStorage 활용
- 요청별 컨텍스트 고립 → AsyncLocalStorage
로 shared state
방지
- 예시: this.localContext.run({ recipients: list }, callback);
결론
- Node.js에서 싱글톤 사용 시 반드시
non-blocking
,stateless
원칙 준수 AsyncLogger
와AsyncLocalStorage
활용해 I/O 차단 및 shared state 문제 해결- 비동기 처리, 배치 처리, 컨텍스트 고립을 통해 서버 확장성 및 안정성 확보