넷플릭스의 마이크로서비스 도입: 아키텍처 설계를 위한 교훈

NGINX | 2015년 2월 19일

최근 몇몇 블로그 게시물에서 저희는 애플리케이션을 여러 4계층 애플리케이션 아키텍처로 개발하고 배포하는 마이크로서비스 방식을 채택하는 것이 왜 중요하다고 생각하는지 설명했습니다. 10년 전에는 아무 문제 없이 통했던 개발 프로세스와 애플리케이션 아키텍처를 계속 사용한다면, 선택할 수 있는 앱이 갈수록 많아지는 모바일 사용자의 관심을 끌고 유지할 만큼 빠르게 대응할 수 없다는 사실이 점점 더 분명해지고 있습니다.

Switching to a 마이크로서비스 아키텍처로 전환하면 기업은 시장에서 흥미로운 기회를 얻을 수 있습니다. 시스템 아키텍트와 개발자는 고객에게 혁신적이고 새로운 웹 경험을 제공하면서 전례 없는 수준의 제어 능력과 속도를 확보할 수 있습니다. 하지만 이처럼 숨 가쁘게 진행되는 상황에서는 실수할 여지가 거의 없다고 느낄 수 있습니다. 현실적으로는 관련 프로세스를 재정비하는 동안에도 애플리케이션 개발과 배포를 중단할 수 없습니다. 미래의 성공이 마이크로서비스 아키텍처로의 전환에 달려 있다는 것은 알지만, 실제로 어떻게 전환해야 할까요?

다행히도 마이크로서비스를 일찍 도입한 여러 선구자들이 이제 오픈 소스 정신에 따라 게시된 코드뿐만 아니라 콘퍼런스 발표와 블로그 게시물을 통해서도 자신들의 전문 지식을 아낌없이 공유하고 있습니다. 그 대표적인 사례가 Netflix입니다. 웹 엔지니어링 디렉터를 거쳐 클라우드 아키텍트로 일한 Adrian Cockcroft는 100명의 엔지니어가 하나의 거대한 DVD 대여 애플리케이션을 개발하던 전통적인 개발 모델에서, 여러 소규모 팀이 수백 개의 마이크로서비스를 처음부터 끝까지 책임지는 마이크로서비스 아키텍처로 전환하는 과정을 이끌었습니다. 이 마이크로서비스들은 서로 연동되어 매일 수백만 명의 Netflix 고객에게 디지털 엔터테인먼트를 스트리밍합니다. 현재 Battery Ventures의 테크놀로지 펠로우인 Cockcroft는 마이크로서비스와 클라우드 네이티브 아키텍처를 널리 알리는 저명한 전도사이며, NGINX 기술 자문 위원회 위원으로도 활동하고 있습니다.

두 편으로 구성된 블로그 게시물 시리즈에서는 Cockcroft가 지난해 10월 제1회 연례 NGINX 컨퍼런스와 그보다 두어 달 앞서 열린 실리콘밸리 마이크로서비스 밋업에서 진행한 두 강연의 핵심 내용을 소개합니다. (전체 동영상 녹화본도 꼭 시청해 볼 만합니다.)

  • 이 글에서는 마이크로서비스 아키텍처를 정의하고 이를 설계할 때 따라야 할 몇 가지 모범 사례를 간략히 소개합니다.
  • Netflix의 마이크로서비스 도입: 팀 및 프로세스 설계를 위한 교훈에서는 소프트웨어 개발에 대한 새로운 사고방식을 도입해야 하는 이유와 방법, 그리고 이를 중심으로 팀을 재편하는 방법을 설명합니다.

마이크로서비스 아키텍처란 무엇인가요?

Cockcroft는 마이크로서비스 아키텍처를 경계가 명확한 컨텍스트를 지닌 느슨하게 결합된 요소들로 구성된 서비스 지향 아키텍처라고 정의합니다.

느슨하게 결합되어 있다는 것은 서비스를 서로 독립적으로 업데이트할 수 있다는 뜻입니다. 즉, 한 서비스를 업데이트할 때 다른 서비스를 변경할 필요가 없습니다. 작고 특화된 서비스가 여러 개 있더라도 항상 함께 업데이트해야 한다면, 느슨하게 결합되어 있지 않으므로 마이크로서비스라고 할 수 없습니다. 마이크로서비스 아키텍처로 전환할 때 흔히 간과하는 결합 유형 중 하나는 데이터베이스 결합입니다. 이는 모든 서비스가 동일한 데이터베이스와 통신하며, 서비스를 업데이트하려면 스키마도 변경해야 하는 경우를 말합니다. 데이터베이스를 분리하고 비정규화해야 합니다.

The concept of 경계가 명확한 컨텍스트라는 개념은 에릭 에반스의 저서 도메인 주도 설계에서 유래했습니다. 컨텍스트의 경계가 올바르게 설정된 마이크로서비스는 소프트웨어 개발 측면에서 독립적으로 완결되어 있습니다. 마이크로서비스와 다른 마이크로서비스는 오직 API를 통해서만 상호 작용하므로 데이터 구조, 데이터베이스 스키마 또는 객체의 기타 내부 표현을 공유하지 않습니다. 따라서 다른 마이크로서비스의 내부를 전혀 몰라도 해당 마이크로서비스의 코드를 이해하고 업데이트할 수 있습니다.

인터넷용 애플리케이션을 개발해 본 적이 있다면, 명칭은 몰라도 실제로는 이미 이러한 개념에 익숙할 것입니다. 대부분의 모바일 앱은 여러 백엔드 서비스와 통신하여 사용자가 앱 안에서 Facebook에 공유하고, Google Maps에서 길을 찾고, Foursquare에서 음식점을 검색하는 등의 작업을 할 수 있게 합니다. 모바일 앱이 이러한 서비스와 긴밀하게 결합되어 있다면, 업데이트를 출시하기 전에 변경 사항으로 인해 문제가 발생하지 않는지 확인하기 위해 해당 서비스의 모든 개발팀과 협의해야 할 것입니다.

마이크로서비스 아키텍처로 작업할 때는 다른 내부 개발 팀을 인터넷 백엔드와 마찬가지로, 즉 마이크로서비스가 API를 통해 상호 작용하는 외부 서비스로 간주합니다. 마이크로서비스 간에 통용되는 “계약”은 API가 안정적이고 향후 버전과도 호환되어야 한다는 것입니다. Google Maps API가 예고 없이 변경되어 사용자에게 문제를 일으키는 것이 용납될 수 없는 것처럼, 여러분의 API도 발전할 수는 있지만 이전 버전과의 호환성을 유지해야 합니다.

마이크로서비스 아키텍처 설계를 위한 모범 사례

Cockcroft는 Netflix의 클라우드 아키텍트로서 자신의 역할을 아키텍처를 통제하는 것이 아니라, Netflix 엔지니어들이 구축하는 과정에서 자연스럽게 형성된 아키텍처를 발견하고 체계화하는 것이라고 설명합니다. Netflix 개발팀은 마이크로서비스 아키텍처를 설계하고 구현하기 위한 몇 가지 모범 사례를 확립했습니다.

각 마이크로서비스별로 별도의 데이터 저장소 만들기

마이크로서비스 간에 동일한 백엔드 데이터 저장소를 사용하지 마세요. 각 마이크로서비스를 담당하는 팀이 해당 서비스에 가장 적합한 데이터베이스를 선택할 수 있어야 합니다. 또한 단일 데이터 저장소를 사용하면 서로 다른 팀이 개발한 마이크로서비스들이 작업 중복을 줄인다는 명목으로 데이터베이스 구조를 공유하기가 너무 쉬워집니다. 결국 한 팀이 데이터베이스 구조를 업데이트하면 해당 구조를 사용하는 다른 서비스도 함께 변경해야 하는 상황이 발생합니다.

데이터를 분리하면 개별 스토리지 시스템 간의 동기화가 어긋나거나 데이터가 불일치하기 쉬워지고 외래 키가 예기치 않게 변경될 수 있으므로 데이터 관리가 더 복잡해질 수 있습니다. 불일치를 찾아 수정하기 위해 백그라운드에서 마스터 데이터 관리(MDM)를 수행하는 도구를 추가해야 합니다. 예를 들어 이 도구는 구독자 ID를 저장하는 모든 데이터베이스를 검사하여 동일한 ID가 모든 데이터베이스에 존재하는지, 즉 특정 데이터베이스에 누락되거나 불필요한 ID가 없는지 확인할 수 있습니다. 이러한 도구를 직접 개발하거나 구매할 수 있습니다. 많은 상용 관계형 데이터베이스 관리 시스템(RDBMS)이 이러한 검사를 수행하지만, 일반적으로 결합에 대한 요구 사항이 너무 많아 확장성이 떨어집니다.

코드의 성숙도를 비슷한 수준으로 유지하기

마이크로서비스 내의 모든 코드는 성숙도와 안정성이 비슷한 수준을 유지하도록 하세요. 즉, 배포되어 원활하게 작동 중인 마이크로서비스의 일부 코드를 추가하거나 다시 작성해야 한다면, 일반적으로 기존 마이크로서비스는 그대로 두고 새 코드나 변경된 코드를 위한 새로운 마이크로서비스를 만드는 것이 가장 좋습니다. [편집자 주 – 이를 불변 인프라 원칙이라고도 합니다.] 이렇게 하면 기존 마이크로서비스의 장애나 성능 저하를 초래할 위험 없이, 새 코드에 버그가 없어지고 효율성이 극대화될 때까지 반복적으로 배포하고 테스트할 수 있습니다. 새 마이크로서비스가 기존 마이크로서비스만큼 안정화되면, 두 서비스가 실제로 함께 하나의 기능을 수행하거나 통합을 통해 다른 효율성을 얻을 수 있는 경우 다시 하나로 합칠 수 있습니다. 하지만 Cockcroft의 경험에 따르면, 마이크로서비스가 지나치게 커져서 분리해야 한다는 사실을 깨닫는 경우가 훨씬 더 흔합니다.

각 마이크로서비스를 별도로 빌드하기

각 마이크로서비스별로 빌드를 따로 수행하여 저장소에서 해당 서비스에 적합한 리비전 수준의 구성 요소 파일을 가져올 수 있도록 하세요. 이로 인해 여러 마이크로서비스가 비슷한 파일 세트를 서로 다른 리비전 수준으로 가져오는 경우가 생길 수 있습니다. 그러면 이전 파일 버전을 폐기해 코드베이스를 정리하기가 더 어려워질 수 있습니다(특정 리비전이 더 이상 사용되지 않는지 더욱 꼼꼼히 확인해야 하기 때문입니다). 하지만 새로운 마이크로서비스를 구축할 때 새 파일을 쉽게 추가할 수 있다는 점을 고려하면 이는 감수할 만한 절충안입니다. 이러한 비대칭성은 의도된 것입니다. 새로운 마이크로서비스나 파일, 함수를 도입하는 일은 위험한 일이 아니라 쉬운 일이어야 합니다.

컨테이너에 배포하기

마이크로서비스를 컨테이너에 배포하는 것이 중요한 이유는 단 하나의 도구만으로 모든 것을 배포할 수 있기 때문입니다. 마이크로서비스가 컨테이너에 들어 있기만 하면 도구가 이를 배포하는 방법을 알 수 있습니다. 어떤 컨테이너인지는 중요하지 않습니다. 그렇기는 하지만 Docker는 매우 빠르게 컨테이너의 사실상 표준으로 자리 잡은 것으로 보입니다.

서버를 무상태로 취급하기

서버, 특히 고객 대상 코드를 실행하는 서버는 그룹 내에서 서로 대체 가능한 구성원으로 취급하세요. 모든 서버가 동일한 기능을 수행하므로 개별 서버에 신경 쓸 필요가 없습니다. 필요한 작업량을 처리할 만큼 충분한 수의 서버가 있는지만 확인하면 되며, 오토스케일링을 사용해 서버 수를 늘리거나 줄일 수 있습니다. 서버 하나가 작동을 멈추면 다른 서버로 자동 교체됩니다. 특정 기능을 수행하기 위해 개별 서버에 의존하는 ‘스노우플레이크’ 시스템은 피하세요.

Cockcroft의 비유에 따르면 서버는 애완동물이 아니라 가축처럼 생각해야 합니다. 프로덕션 환경에서 특수한 기능을 수행하는 머신이 있고, 그 머신을 이름으로 부르며, 머신이 중단되면 모두가 안타까워한다면 그것은 애완동물입니다. 그보다는 서버를 소 떼처럼 생각해야 합니다. 중요한 것은 우유를 몇 갤런이나 얻느냐입니다. 어느 날 평소보다 우유 생산량이 줄었다는 사실을 알게 되면, 생산성이 떨어진 소를 찾아 교체하면 됩니다.

Netflix 전송 아키텍처는 NGINX를 기반으로 구축됩니다

Netflix는 오랫동안 NGINX Open Source를 사용해 왔으며, 2011년 NGINX, Inc.가 법인으로 설립된 후 첫 번째 고객이 되었습니다. 실제로 Netflix는 NGINX를 선택하여 자사의 콘텐츠 전송 인프라인 Open Connect의 핵심으로 삼았습니다. Open Connect는 세계 최대 규모의 콘텐츠 전송 네트워크(CDN) 중 하나입니다. 초당 수천 건, 때로는 수백만 건의 요청을 처리할 수 있는 NGINX와 NGINX Plus는 고성능 HTTP 전송을 위한 최적의 솔루션으로, Netflix와 같은 기업이 매일 수백만 명의 고객에게 고품질 디지털 경험을 제공할 수 있도록 지원합니다.

동영상 녹화본

빠른 전송
nginx.conf 2014, 2014년 10월

마이크로서비스로의 마이그레이션, 1부
실리콘밸리 마이크로서비스 밋업, 2014년 8월

마이크로서비스로의 마이그레이션, 2부
실리콘밸리 마이크로서비스 밋업, 2014년 8월


공유
태그: F5 NGINX, Tech

관련 블로그 게시물

시청하기: KubeCon North America 2023에서의 NGINX Gateway Fabric
NGINX | 2023. 11. 30.

시청하기: KubeCon North America 2023에서의 NGINX Gateway Fabric

이 영상에서는 KubeCon의 NGINX 부스를 찾아가, 저희가 공개한 Kubernetes Gateway API 구현을 살펴봅니다.

F5 NGINX로 대규모 WAF 플릿을 확인하고 관리하는 2가지 방법
NGINX | 2023. 03. 23.

F5 NGINX로 대규모 WAF 플릿을 확인하고 관리하는 2가지 방법

앱 보안을 강화하는 두 가지 방법을 소개합니다. NGINX Management Suite를 통해 WAF 운영에 대한 가시성을 높이고, NGINX App Protect WAF를 활용해 코드형 보안을 구현하는 것입니다.

Ingress 컨트롤러 선택 가이드, 4부: NGINX Ingress Controller 옵션
NGINX | 2021. 09. 27.

Ingress 컨트롤러 선택 가이드, 4부: NGINX Ingress Controller 옵션

개발 주체, 개발 철학, 프로덕션 환경 준비도, 보안 및 지원을 기준으로 어떤 NGINX Ingress 컨트롤러가 가장 적합한지 알아보세요.

진화하는 공격 환경에 NGINX App Protect Denial of Service가 적응하는 방법
NGINX | 2021. 07. 06.

진화하는 공격 환경에 NGINX App Protect Denial of Service가 적응하는 방법

NGINX App Protect Denial of Service(DoS)가 계층 7 DoS 공격을 방어하기 위해 완화 방법을 실시간으로 조정하는 방식을 설명합니다. 정상적인 사용자 행동과 서버 상태에 대한 모델을 생성하여 공격을 나타내는 이상 징후를 감지하고 맞춤형 완화 시그니처를 적용할 수 있습니다.

NGINX Instance Manager를 활용한 대규모 구성 업데이트 및 인증서 관리
NGINX | 2021. 06. 30.

NGINX Instance Manager를 활용한 대규모 구성 업데이트 및 인증서 관리

NGINX Instance Manager 버전 1.0에는 두 가지 새로운 기능이 도입되었습니다. NGINX 인스턴스에 태그와 사용자 역할을 지정하면 전체 그룹에 구성을 한 번에 적용할 수 있습니다. 인증서 검사는 만료 예정인 인증서를 감지하여 서비스 중단을 방지할 수 있도록 인증서를 교체할 수 있게 해줍니다.

Netflix가 자사 CDN의 핵심으로 NGINX를 선택한 이유
NGINX | 2015. 03. 25.

Netflix가 자사 CDN의 핵심으로 NGINX를 선택한 이유

Netflix가 글로벌 콘텐츠 전송 네트워크인 Open Connect의 스트리밍 미디어 기술로 NGINX를 선택한 이유를 NGINX 개발자 Gleb Smirnoff에게서 알아보세요.