실시간 웹이 만들어지기까지

[27M05] Building Real Time Web / Makoto Inoue (New Bamboo (London, UK))

작성자
RubyKaigi
발행일
2025년 10월 05일

핵심 요약

  • 1 Pusher는 HTML5 WebSocket 기술을 활용하여 실시간 웹 기능을 제공하는 클라우드 서비스로, Node.js를 통한 초기 탐색 후 Ruby를 백엔드로 채택하여 개발되었습니다.
  • 2 WebSockets 프로토콜의 진화, 브라우저 호환성(IE/iPhone), 확장성 및 프록시 우회 등 실시간 웹 서비스 개발 및 운영 시 직면하는 주요 과제와 해결책을 제시합니다.
  • 3 WebSockets의 단순한 API를 보완하기 위해 채널 및 이벤트 개념을 도입하고, Redis 및 RabbitMQ를 활용하여 고성능 및 확장성을 확보한 Pusher의 아키텍처를 설명합니다.

도입

본 발표는 New Bamboo의 이노우에 마코토(Inoue Makoto) 씨가 자사의 실시간 웹 서비스인 Pusher의 개발 과정을 소개합니다. Pusher는 HTML5 WebSocket을 기반으로 웹 애플리케이션에 실시간 푸시 기능을 제공하는 클라우드 서비스입니다. 발표는 Node.js를 활용한 초기 WebSockets 탐색부터 Ruby를 백엔드로 사용한 서비스 구현, 그리고 실제 서비스 운영에서 마주한 기술적 도전과 해결책까지 포괄적으로 다룹니다.

1. WebSockets의 등장과 Node.js의 역할

  • Node.js의 활용: 2009년 말 Node.js의 비동기 이벤트 루프 모델이 WebSockets의 상시 연결 특성과 잘 맞물린다고 판단, 초기 WebSockets 기능 구현에 Node.js를 활용했습니다.

  • WebSockets의 특징:
    • HTTP와 동일한 포트(80/443) 사용, HTTP 요청으로 시작하여 Upgrade 헤더를 통해 WebSockets 연결로 전환.
    • 연결이 유지(Connection Keep-Alive)되어 TCP와 유사한 상시 연결 제공.
    • 프레임 단위 데이터 전송으로 기존 Ajax(폴링)나 Comet(롱 폴링) 방식 대비 오버헤드가 현저히 낮고 효율적입니다.
  • JavaScript API: WebSocket 객체 생성, onopen, onmessage, onclose 콜백 함수 설정, send 메서드를 통한 데이터 전송 등 매우 단순한 API 구조를 가집니다.

2. WebSockets의 브라우저 지원 및 과제

  • 지원 현황: Chromium, Safari 5, Firefox 4 베타 등 주요 브라우저에서 WebSockets가 구현되기 시작했습니다.

  • 프로토콜 변화: 초기 드래프트 버전(75, 76) 간의 비호환성으로 기존 라이브러리가 무용지물이 되는 문제가 발생했습니다.

  • IE 및 모바일 대응:
    • IE는 WebSockets를 직접 지원하지 않으므로, Flash를 이용한 에뮬레이션 라이브러리(예: web-socket-js)를 통해 호환성을 확보했습니다.
    • iPhone/iPad는 Flash를 지원하지 않으므로, PhoneGap과 Objective-C를 연동하는 방식으로 우회 구현이 가능합니다.
  • 데이터 형식: 초기에는 UTF-8 텍스트 전송이 권장되었으며, 바이너리 전송은 아직 실험적 단계였습니다.

3. Ruby 기반 WebSockets 구현

  • Ruby 라이브러리 소개:
    • EM-Websocket: EventMachine 기반의 라이브러리.
    • Rev-Websocket: Rev 프레임워크 기반의 라이브러리.
    • Cramp: 37signals의 Pratik Naik이 개발한 프레임워크로, 컨트롤러 개념을 도입하고 HTTP 서버와 WebSockets를 통합할 수 있습니다.
    • Rainbows: 다양한 동시성 모델(스레드 풀, 액터)을 전환할 수 있는 유연성을 제공합니다.
  • 라이브러리 선택 기준:
    • 최신 WebSockets 드래프트 버전(76) 지원 여부.
    • 단순 라이브러리 또는 프레임워크 형태(Cramp처럼 HTTP 서버와 통합 가능 여부).
    • 성능: EventMachine 기반 라이브러리들은 높은 성능을 보이며, 벤치마크 결과 Node.js와 유사한 수준의 동시 연결 처리 능력을 보여주었습니다.

4. Pusher 아키텍처 및 확장성

  • 서비스 모델: 기존 웹 애플리케이션(Rails 등)과 Pusher WebSockets 서버를 분리하여, 클라이언트가 Pusher 서버에 직접 연결하고, 웹 서버는 REST API 호출을 통해 Pusher 서버로 데이터를 푸시하는 방식입니다. 이는 크로스 도메인 WebSockets 연결이 가능하다는 점을 활용합니다.

  • Pusher의 추상화: 단순한 WebSockets API를 보완하기 위해 채널(Channel)이벤트(Event) 개념을 도입하여 특정 채널에 메시지를 보내거나 사용자 정의 이벤트에 바인딩할 수 있도록 했습니다.

  • 확장성 확보:

    • 세션 관리: Redis를 사용하여 세션 ID 룩업 및 관리를 최적화했습니다.
    • 서버 간 통신: 여러 Pusher 프로세스 간의 메시지 브로드캐스팅을 위해 RabbitMQ와 같은 메시지 큐 시스템을 활용하여 Pub/Sub 모델을 구현했습니다.
    • 프록시 우회: 기업 환경의 방화벽 및 프록시 문제를 해결하기 위해, 80번 포트 연결 실패 시 자동으로 443번 TLS 포트를 사용하여 연결을 시도하는 전략을 채택했습니다.

결론

Pusher는 실시간 웹 구현의 복잡성을 해결하고 개발자들이 손쉽게 실시간 기능을 통합할 수 있도록 돕는 클라우드 서비스입니다. Node.js로 시작된 WebSockets 탐색은 Ruby 기반의 견고한 백엔드 서비스로 발전했으며, 프로토콜 변화, 브라우저 호환성, 그리고 서비스 확장성이라는 다양한 도전 과제를 효과적으로 극복했습니다. Pusher는 WebSockets의 단순성을 보완하는 추상화 계층과 Redis, RabbitMQ 등을 활용한 분산 아키텍처를 통해 안정적이고 확장 가능한 실시간 웹 환경을 제공하며, 이는 현대 웹 애플리케이션 개발에 중요한 시사점을 제공합니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!