프로젝트 깃허브
이번 주 동안 Node.js 환경에서 포인트 시스템의 동시성 제어 프로젝트를 진행하면서 겪었던 기술적 문제와 그 해결 과정에 대해 공유하고자 합니다!
1. 문제 (과제, 프로젝트를 진행하면서 부딪혔던 기술적인 문제)
프로젝트를 진행하면서 가장 큰 문제는 Node.js의 싱글 스레드 특성과 동시성 제어 요구사항 사이의 충돌이었습니다. 특히, 다음과 같은 구체적인 문제에 직면했습니다:
- 여러 사용자가 동시에 포인트를 충전하거나 사용할 때 데이터 정합성을 유지하는 것이 어려웠습니다.
- 전통적인 스레드 기반의 락(lock) 메커니즘을 그대로 사용할 수 없었습니다.
- 락을 구현하더라도 Node.js의 이벤트 루프를 블로킹하지 않으면서 동시성을 제어해야 했습니다.
2. 시도
이 문제들을 해결하기 위해 다음과 같은 시도를 했습니다:
- 먼저, 비관적 락(Pessimistic Lock)과 낙관적 락(Optimistic Lock)에 대해 깊이 연구했습니다.
- Node.js 환경에 적합한 락 구현 방식을 찾기 위해 여러 라이브러리와 패턴을 조사했습니다.
- 스핀락(Spinlock) 개념을 Node.js의 비동기 특성에 맞게 변형하여 구현해보았습니다.
- 사용자별로 독립적인 락을 관리하기 위해 Map 자료구조를 활용해보았습니다.
3. 해결
최종적으로 문제를 다음과 같이 해결했습니다:
- TimeoutSpinLock 클래스를 구현하여 비동기적으로 동작하는 스핀락을 만들었습니다.
- LockManager 클래스를 싱글톤 패턴으로 구현하여 사용자별로 독립적인 락을 관리했습니다.
- async/await와 Promise를 활용하여 Node.js의 이벤트 루프를 블로킹하지 않으면서도 효과적인 동시성 제어를 구현했습니다.
- 타임아웃 메커니즘을 추가하여 무한 대기 상태를 방지하고 시스템 안정성을 높였습니다.
4. 알게된 것
이 과정을 통해 새롭게 알게 된 것들은 다음과 같습니다:
- Node.js의 싱글 스레드 특성을 고려한 동시성 제어 방식: 전통적인 멀티스레드 환경과는 다른 접근이 필요하다는 것을 깨달았습니다.
- 비동기 프로그래밍의 중요성: async/await와 Promise를 효과적으로 활용하면 복잡한 동시성 문제도 우아하게 해결할 수 있다는 것을 배웠습니다.
- 타임아웃의 중요성: 분산 시스템에서 타임아웃 처리가 시스템의 안정성과 신뢰성을 높이는 데 큰 역할을 한다는 것을 알게 되었습니다.
- 테스트 주도 개발(TDD)의 가치: 복잡한 동시성 시나리오를 테스트 케이스로 작성하면서, TDD가 복잡한 시스템 개발에 큰 도움이 된다는 것을 체감했습니다.
- 자료구조의 중요성: Map을 활용한 락 관리를 통해, 적절한 자료구조 선택이 시스템 설계와 성능에 미치는 영향을 이해하게 되었습니다.
이번 프로젝트를 통해 Node.js 환경에서의 동시성 제어에 대해 깊이 있게 학습할 수 있었습니다.
하지만, 아직 애플리케이션 레벨에서만 락을 사용한 것이기 때문에! 분산 환경을 고려하지 않은 설계일입니다.
다음 주차에는 데이터베이스를 실제로 연결한 다음 분산 환경에서의 동시성 처리 로직을 만들어 보고자 합니다!