Meteor 3.5를 사용하면 개발자는 단 하나의 환경 변수만으로 SockJS 대신 uWebSockets.js를 사용할 수 있으며, 메서드 호출에 크게 의존하는 앱의 경우 CPU, RAM 및 가비지 컬렉션(garbage-collection) 비용을 눈에 띄게 낮출 수 있습니다.

이번 변화가 중요한 이유

출시 이후 Meteor는 모든 DDP(Distributed Data Protocol) 메시지를 SockJS를 통해 전달해 왔습니다. SockJS는 어디서나 작동하는 JavaScript 폴백(fallback)이지만, 순수 속도를 위해 설계되지는 않았습니다. 이번 새 버전은 전송 계층(transport layer)을 분리하여, DDP의 요구 사항을 준수하는 모든 WebSocket 구현체를 수용할 수 있는 플러그인 지점을 제공합니다. 실행 시 DDP_TRANSPORT=uws를 설정하면 기본값을 높은 처리량으로 유명한 C/C++ 기반 서버인 uWebSockets.js로 교체할 수 있습니다.

성능 측면

이번 릴리스와 함께 제공된 벤치마크 결과는 다음과 같습니다:

  • CPU 사용량 9% 감소
  • RAM 소비량 11% 감소
  • 가비지 컬렉션 일시 중지 시간 26% 단축
  • 마이크로 벤치마크에서 처리량(Throughput) 1.6배 향상

이러한 이점은 애플리케이션이 많은 RPC 방식의 메서드 호출을 수행할 때 나타납니다. 전송 계층 자체가 병목 현상이 되는 시점은 애플리케이션의 비즈니스 로직이 최적화된 이후이므로, 이번 전환은 서버 비용 절감으로 직접 이어질 수 있습니다.

지금 바로 사용해 보는 방법

별도의 바이너리는 필요하지 않으며, Meteor 3.5만 있으면 됩니다. 다음과 같이 앱을 실행하세요:

DDP_TRANSPORT=uws meteor run

uWebSockets.js 서버는 자체 포트(기본값 5001)에서 대기합니다. 여러 Meteor 인스턴스가 하나의 호스트를 공유하는 경우, 충돌을 방지하기 위해 METEOR_SETTINGS를 통해 각 인스턴스에 고유한 uws.port를 할당해야 합니다.

혜택을 받는 대상과 차이를 느끼기 어려운 대상

  • RPC 중심의 워크로드 – 요청당 많은 메서드를 호출하는 서비스는 CPU 사이클과 메모리를 절약할 수 있어 확장(scaling) 압박을 완화할 수 있습니다.
  • Pub/Sub 중심의 앱 – 발행/구독(publish/subscribe) 패턴의 지연 시간 대부분은 전송 계층이 아닌 데이터 차이(data-diff) 계산에서 발생하므로, 속도 향상은 미미할 수 있습니다.

이번 변경 사항은 선택 사항(opt-in)입니다. SockJS가 기본값으로 유지되므로, 네이티브 WebSocket을 사용할 수 없는 환경과의 호환성도 보장됩니다.

트레이드오프 및 주의 사항

전송 계층을 전환하면 추가적인 운영 단계가 발생합니다. 즉, 추가 포트를 관리하고 다른 서비스와 충돌하지 않도록 확인해야 합니다. uWebSockets.js는 네이티브 모듈이므로 바이너리 의존성에 따른 일반적인 고려 사항이 따릅니다. 배포 호스트에 빌드 도구가 설치되어 있어야 하며, 향후 라이브러리가 업데이트될 경우 애플리케이션 코드베이스와의 호환성을 테스트해야 합니다.

Meteor 전송 계층의 향후 전망

명확한 경계를 노출함으로써, Meteor는 이제 커뮤니티가 특수한 보안 요구 사항, 사용자 정의 프로토콜 확장 또는 추가적인 성능 튜닝을 위해 대안적인 전송 계층을 실험해 볼 수 있도록 길을 열어주었습니다. 서드파티 구현체가 얼마나 빠르게 등장하는지를 보면, 이 플러그형 모델이 Meteor 아키텍처의 지속적인 구성 요소가 될 수 있을지 알 수 있을 것입니다.

요약: Meteor 3.5의 플러그형 DDP 전송 계층을 사용하면 단 한 번의 명령으로 기존 SockJS 스택을 uWebSockets.js로 교체할 수 있습니다. 이를 통해 RPC 집약적인 애플리케이션에서 최대 1.6배 높은 처리량과 눈에 띄는 리소스 절감 효과를 얻을 수 있으며, 성능 향상이 필요 없는 워크로드에 대해서는 기존 설정을 그대로 유지할 수 있습니다.