이벤트 기반 프로그래밍으로 C++ 대규모 동시 연결 처리
AI Store에서 AI코딩으로 만들어진 앱을 만나보세요!
지금 바로 방문하기

이벤트 기반 프로그래밍으로 대규모 동시 연결 처리: C++에서의 실전 경험

카테고리

프로그래밍/소프트웨어 개발

서브카테고리

웹 개발

대상자

- 대상: C++ 네트워크 서버 개발자, 고성능 서버 아키텍처 설계자

- 난이도: 중급 이상 (시스템 콜, 블로킹/논블로킹 I/O, 동시성 관리 이해 필요)

핵심 요약

  • C10K 문제는 10,000개 동시 연결 처리를 위한 근본적 아키텍처 한계를 의미하며, 이벤트 기반 프로그래밍이 해결책임.
  • epoll/kqueue 시스템 콜을 통해 I/O 멀티플렉싱을 구현하여, thread-per-connection 모델 대신 이벤트 루프를 사용해야 함.
  • ConnectionState 구조체와 shared_ptr + mutex를 사용한 스레드 안전한 연결 상태 관리가 핵심.
  • HTTP 헤더 파싱은 "folding", "Content-Length 누락" 등 복잡한 경계 조건을 고려해야 함.

섹션별 세부 요약

1. Thread-per-Connection 모델의 한계

  • 200개 동시 연결 시 메모리 사용량 폭증 및 CPU 스레드 전환 비용으로 서버가 완전히 연결 거부하게 됨.
  • C10K 문제는 실무에서 반드시 고려해야 할 서버 확장성 한계로, thread-per-connection 모델은 이를 극복할 수 없음.
  • 이벤트 기반 프로그래밍은 스레드 대신 I/O 멀티플렉싱을 통해 동시 연결을 효율적으로 처리.

2. 이벤트 기반 프로그래밍과 I/O 멀티플렉싱

  • epoll (Linux)과 kqueue (macOS/BSD)는 이벤트 중심의 I/O 감지 기법으로, edge-triggered 모드로 최적화됨.
  • EPOLLET 플래그를 사용해 데이터 상태 변화만 감지하며, 한 번에 모든 데이터 읽기가 필요함.
  • kqueueEVFILT_READ필터 기반으로 이벤트 등록, API 차이를 추상화EventNotifier 클래스 구현.

3. 이벤트 루프 구현

  • EventLoop::run() 메서드는 1초 타임아웃으로 이벤트 대기, wait_for_events() 호출 시 모니터링 중인 파일 디스크립터의 활동 감지.
  • 타임아웃 매커니즘은 서버 유지보수 및 종료 신호 처리에 필수적.

4. 연결 상태 관리

  • ConnectionState 구조체는 소켓 파일 디스크립터, HTTP 버퍼, 마지막 활동 시간 등을 저장.
  • 스레드 안전한 연결 관리를 위해 std::shared_ptrstd::mutex 사용, 락은 단기 유지.

5. HTTP 요청 파싱의 복잡성

  • HTTP 헤더 folding (다중 줄 헤더), Content-Length 누락, 지속적 요청경계 조건 대응 필요.
  • HttpRequestTask::execute()에서 \r\n\r\n 기준으로 헤더 파싱, HTTP 버퍼링을 통해 부분 요청 처리.

결론

  • 고성능 서버 개발 시 이벤트 루프I/O 멀티플렉싱(epoll/kqueue) 사용이 필수적.
  • ConnectionState스레드 안전한 구조를 통해 연결 상태를 효율적으로 관리해야 함.
  • HTTP 파싱은 헤더 folding, Content-Length 처리 등 복잡한 경계 조건을 반드시 고려해야 함.
  • C10K 문제 해결을 위해 thread-per-connection 모델 대신 이벤트 기반 아키텍처를 도입해야 함.