Node.js 활용 사례 - Netflix

2009년 Node.js가 등장한 이래 Node.js는 현대 소프트웨어 개발에서 매우 중요한 역할을 하고 있습니다. 그러한 역할은 산업 전반의 다양한 활용 사례를 통해 입증되고 있습니다. 이 글은 그 활용 사례중 한 도입 사례를 한 발 더 깊이 연구해봅니다. 무엇이 문제였는지, 그리고 그 문제 해결에 어떻게 도움이 되었는지 확인해 봄으로서 Node.js의 가치를 좀 더 가늠해 보려합니다.

배경

넷플릭스는 2015년경부터 자사의 앱 스택에 Node.js를 적용하는데 그 당시 Netflix는 사용자 사용 앱의 '익터랙티브 시간' (TTI: Time To Interactive) 를 줄이고자 하는 목표를 가지고 있었습니다. '익터랙티브 시간' 이란 어플리케이션 최초 시작 시점부터 UI 가 사용자에 의해 상호작용이 가능한 시간까지의 첫 시점을 의미합니다. 이 TTI라는 지표를 원하는 수치 달성하기 위해 개선에 집중한 영역은 아래와 같았습니다.

서버 랜더링 - 클라이언트 렌더링, 그리고 Universal Javascript

웹 어플리케이션을 작성할때 애플리케이션의 특성과 요구사항에 따라 서버 혹은 클라이언트 렌더링을 고려해 설계합니다. 서버 렌더링(Server-side rendering)은 웹 애플리케이션에서 클라이언트 측에서 화면을 구성하는 대신 서버에서 HTML을 생성하여 클라이언트에게 제공하는 방식입니다. 이는 클라이언트 측에서 자바스크립트를 실행하여 화면을 동적으로 렌더링하는 클라이언트 사이드 렌더링(Client-side rendering)과 대조적인 방법입니다.

서버 렌더링은 서버 측에서 마크업을 생성하므로 초기 로딩 속도가 개선될 수 있습니다. 사용자는 초기 페이지 로드 후에 즉시 내용을 볼 수 있으며, 검색 엔진 최적화 (SEO)에도 도움이 될 수 있습니다. 클라이언트 렌더링은 JavaScript를 사용하여 동적인 UI를 쉽게 구현할 수 있습니다. 사용자의 상호작용에 따라 즉각적인 업데이트와 상태 변경이 가능하며, 더 나은 사용자 경험을 제공할 수 있습니다.

서버 렌더링, 클라이언트 렌더링은 프로젝트의 목표, 성능 요구사항, 개발자 경험 및 유지 보수 등을 고려하여 결정해야하나 넷플릭스가 Node.js 도입시 가졌던 문제는 이러한 서버 렌더링과 클라이언트 렌더링을 유연하게 설계하는 것이 어려웠던 것이었습니다. 그리고 그 어려움의 가장 큰 이유가 양측에서 사용하는 언어가 서로 다른 점이었습니다.

두 언어를 상호 전환하는 데에는 기본적으로 비용을 수반하며, 렌더링을 유연하기 위해 마크업을 개선하기 위해서는 클라이언트 코드와 너무 많은 직접적인 커플링이 발생합니다. 이에 대한 여러 솔루션이 있으나 양쪽이 같은 언어를 사용했을때 언어의 다름으로 인해 렌더링 결과의 미세한 차이가 발생 할 수 있는 있다는 것을 확인하였으며 이로 인해 모든 마크업이 동일 언어에서 제공하는 한 API를 사용하여 구성하는 것이 이상적이다라고 판단하게 되었습니다.

Monolithic 아키텍쳐에서 Service 기반 아키텍쳐로

Monolithic 은 "하나로 통합된" 이라는 의미를 가지며, 애플리케이션의 모든 구성 요소가 단일한 실행 가능한 단위로 구성되는 것을 의미합니다. 일반적으로 단일 코드베이스로 구성되며, 모든 기능과 서비스가 하나의 애플리케이션 내에 존재합니다. Netflix는 기존 앱은 Monolithic 한 형태로 설계되어 있었으며 [[Java EE]] (자바 엔터프라이즈 에디션) 기반으로 작성되어 있었습니다.

엔터프라이즈 자바(Enterprise Java)는 기업 환경에서 대규모 응용 프로그램을 개발하고 구축하는 데 사용되는 자바 기반의 기술과 플랫폼을 가리킵니다. 엔터프라이즈 자바는 자바 엔터프라이즈 에디션(Java EE) 스펙의 일부로 제공되며, 기업급 시스템에서 안정성, 확장성, 보안성 등의 요구사항을 충족시키기 위한 다양한 기능과 도구를 제공합니다.

또 자체 데이터 서버를 가지고 있어 서버, 스토리지, 네트워크 장비 등을 직접 관리하였습니다. 이러한 데이터 서버 유지 및 스케일링에 대한 관리 비용을 효율화하고자, 인터넷 컴퓨터 리소스인 클라우드를 활용하기로 결정하였습니다.

Monolithic 아키텍처는 전체 어플리케이션을 단일 단위로 배포하고 실행합니다. 그렇기 때문에 클라우드 환경에서는 기능의 독립적인 확장이 어렵고, 전체 어플리케이션을 확장해야하기 때문에 리소스 사용이 비효율적일 수 있습니다. 또 개발 및 배포가 어렵고, 장애발생시 회복시키거나 장애를 격리하기가 어렵습니다. 이러한 이유로인해 Netflix는 기존의 Monolithic Java 서비스 였던 애플리케이션을 더 작은 집합 (Microservice)으로 해체하고자 하였습니다.

Node.js 와 React.js

상기 두 개선 영역을 해결하고자 넷플릭스는 Node.js와 React.js를 도입하였습니다. Node.js 런타임내 React.js를 사용하여 서버와 클라이언트의 렌더링 로직을 공유할 수 있었습니다. 예를 들어, React 컴포넌트를 서버 측에서 렌더링하여 초기 마크업을 생성한 후, 클라이언트에서는 해당 컴포넌트를 가져와 상호작용을 처리하고 동적으로 업데이트할 수 있습니다. 이를 통해 서버와 클라이언트 간에 렌더링 로직을 공유하여 일관성을 유지하고 개발 유연성, 생산성을 향상시킬 수 있습니다.

또 Monolithic Java 서비스를 해체하여 구동하는데 Node.js를 활용하였는데, 그 이유중 하나는 Node.js 가 마이크로 서비스 구축에 적합한 솔루션이였기 때문이었습니다. Node.js는 싱글 스레드 이벤트 큐로 구성된 'Event-Driven' 아키텍쳐를 가지고 있습니다. 이러한 구조는 비동기 I/O 처리를 위해 많은 수의 동시 요청을 처리할 수 있으며, 이벤트가 발생할 때 다른 서비스나 외부 시스템과의 상호작용을 단순화 할 수 있습니다. Java 기반 애플리케이션 대비 시스템 구동, 통신등에 있어 자원 사용 및 오버헤드가 적다는 것도 마이크로 서비스간 빈번한 상호작용과 빠른 응답성에도 유리하였습니다.

결론

활용사례를 조사해보며 해당 기업이 Node.js를 도입하고자 했던 문제와 가치를 좀 더 잘 이해할 수 있었습니다. 비슷한 문제를 가진 프로젝트와 기업에서도 Node.js를 솔루션으로서 고려해 볼 수 있을것 입니다.

또한 어떤 한 솔루션이 프로덕션 레벨의 기술 스택으로 사용되기 위해서는 여러 가지 신뢰성과 관련된 의문을 해결해야 하는데, 조사를 하며 Netflix를 비롯하여 이미 많은 회사에서 Node.js를 자사 서비스 구조의 주요 축으로서 성공적으로 적용한 사례가 있었습니다. 이는 현재 Javascript 런타임이 다양하게 등장하고 있는 시대에 있어서 솔루션 선택에 있어서 중요한 지표가 될 수 있다고 생각됩니다.

아래 다른 적용 사례에 대한 리스트를 첨부합니다

Share