Skip to content

[번역] 모놀리식 아키텍처(Monolithic Architecture) #
Related pages Similar titles

You are seeing an old version of the page. Go to latest version

패턴: 모놀리식 아키텍처 (Monolithic Architecture) #

맥락 (Context) #

서버 사이드 기업용 애플리케이션 개발을 하고 있다고 해보자. 데스크탑 브라우저와 모바일 브라우저, 그리고 네이티브 모바일 애플리케이션을 포함해 여러 가지 다양한 클라이언트 지원해야만 한다. 또한, 애플리케이션은 3rd 파티가 사용할 수 있도록 API를 노출해야 할 수도 있다. 또한 웹서비스나 메시지 브로커를 통해서 다른 애플리케이션 서비스와 통합해야 할 수도 있다. 애플리케이션은 비즈니스 로직을 실행하고, 데이터베이스에 접근하며, 다른 시스템들과 메시지를 주고받아 HTML/JSON/XML 응답을 돌려주는 것으로 요청(HTTP 요청과 메시지)을 처리한다

애플리케이션은 계층형 아키텍처나 6방형(hexagonal) 아키텍처를 갖거나 다양한 유형의 컴포넌트로 구성되어 있다.

  • 프리젠테이션 컴포넌트- HTTP 요청을 제어해서 HTML이나 JSON/XML(웹서비스 API들로써)로 응답을 보내는 책임
  • 비즈니스 로직- 애플리케이션의 비즈니스 로직
  • 데이터베이스 접근 로직 - 데이터베이스에 접근해서 데이터 접근 객체 만드는 책임
  • 애플리케이션 통합 로직 - 메시지 처리 레이어를 말하며, Spring Integration을 기반으로 하는 걸 예로 들 수 있음

이들은 애플리케이션의 다양한 기능적인 측면에 상응하는 논리적인 컴포넌트이다.

문제 (Problem) #

애플리케이션의 배포 아키텍처는 어떤 것인가?

영향도 (Forces) #

  • 애플리케이션을 개발하는 개발자들의 팀
  • 새로운 팀원은 빠르게 생산성을 보여줘야 함
  • 애플리케이션은 쉽게 이해하고, 수정할 수 있어야 함
  • 애플리케이션의 지속적인 배포가 관례화 되기를 기대함
  • 규모가변성(Scalability) 와 가용성(Availability) 요구사항을 만족하기 위해서 다수의 장비에서 애플리케이션의 다수의 복사본이 실행되야 함
  • 최근 부각된 기술(프레임워크, 프로그래밍 언어 등)을 기회로 활용되기를 원한다.

해결방법 (Solution) #

모놀리식 아키텍처를 사용해서 애플리케이션을 구축한다. 예를 들면, 단일 자바 WAR 파일 Rails 또는 NodeJS 코드의 단일 디렉토리 구조

예시 #

고객에서 주문까지, 재고(inventory)를 확인하고, 신용결재(credit)가 가능하며, 이를 출하(ships)할 수 있는 전자 상거래 애플리케이션을 구축한다고 상상해보자. 애플리케이션은 신용거래를 확인하고, 재고를 관리하고, 주문을 출하하는 백 엔드 서비스와 함께 사용자 인터페이스를 구현하는 StoreFrontUI를 포함하는 각각 컴포넌트로 구성한다.

애플리케이션은 단일 모놀리식 애플리케이션으로 배포된다. 예를 들어, 톰캣과 같은 웹 컨테이너에서 실행되는 하나의 WAR 파일로 구성 된 자바 웹 애플리케이션이거나 Apache/Nginx나 톰캣의 JRuby에서 돌아가는 Phusion Passenger를 사용한 단일 디렉토리 구조로 구성된 Rails 애플리케이션일 수 있다. 스케일 확보와 가용성 증대를 위해 로드 발란서(load balancer) 뒤에서 다수의 인스턴스를 실행할 수 있다.

app

상황 해결하기 #

이 해결책은 여러 장점을 가지고 있다.

  • 개발의 단순함: 현재의 개발 툴과 IDE의 목표는 모놀리식 애플리케이션의 배포를 지원이다.
  • 배포의 단순함: 적절한 런탐임 환경에 WAR 파일을 간단하게 배포해야 한다.
  • 확장의 단순함: 로드 발란서 뒤에 애플리케이션의 다수의 복사본을 실행해서 애플리케이션 스케일 확보해야 한다.

그렇지만 일단 애플리케이션이 커지고 팀의 규모가 성장하면 이 접근방법은 가면 갈수록 심각해지는 여러 단점이 발생한다.

  • 큰 모놀리식 코드 기반은 개발자들을 위축시키며, 특히, 팀에 새로운 개발자에게는 더 그렇다. 애플리케이션은 이해하기 어렵고, 수정하기 어려워질 수 있다. 결과적으로 보통 개발은 점점 더 느려지며, 물리적인 모듈 경계가 없기 때문에 모듈화는 시간이 지나면 지날수록 깨진다. 게다가 변경을 정확하게 구현하려면 어떻게 해야 하는지 이해하기 어렵기 때문에 시간이 지날수록 코드의 품질은 나선형으로 떨어진다.
  • IDE 과부하 - 코드 기반이 더 커지면 IDE 속도를 더 느리게 만들고어서 개발자 생산성은 떨어진다.
  • 웹 컨테이너 과부하 – 애플리케이션이 더 커지면서 애플리케이션을 시작하기가 점점 더 오래 걸린다. 이 문제는 컨테이너가 시작되기를 기다리는 시간을 허비해 개발자 생산성에 큰 영향을 준다.
  • 지속적인 배포 어려움 – 또한 모놀리식 아키텍처가 커질수록 빈번한 배포에 장애물이 된다. 하나의 컴포넌트를 갱신하고 싶을 때 전체 시스템을 재 배포 해야 한다. 이는 변경 영향도가 있든 없든 혹시나 문제의 원인이 될까 봐 백그라운드 작업(일례로 자바 애플리케이션에서 Quartz 잡)을 중단하게 한다. 또한 컴포넌트가 갱신되지 못하면 정확한 기동이 실패할 수 있다. 결과적으로 재 배포에 관련된 위험은 증가하며, 빈번한 갱신을 막게 된다. 이 점은 특히 보통 빠르게 반복하면서 자주 재 배포를 필요로 하는 사용자 인터페이스 개발자에게 특히 문제이다.
  • 애플리케이션 스케일 확보의 어려움 – 모놀리식 아키텍처는 한 가지 관점으로만 스케일 확보를 할 수 있다. 반면에 애플리케이션의 복사본을 더 만들어 실행함으로써 트랜잭션 용량을 증가시켜 스케일 확보를 할 수 있다. 일부 클라우드는 부하량에 따라 동적으로 인수턴스의 수까지 조정 할 수 있다. 하지만 한편으로 이 아키텍처는 데이터 용량을 증가시켜 스케일 확보는 불가능하다. 애플리케이션 인스턴스의 각 복사본은 모든 데이터에 접근할 수 있으며, 이는 캐시 효율성을 떨어트리고, 메모리 소비와 I/O 트랙픽을 증가시킨다. 또한 다른 애플리케이션 컴포넌트는 다른 리소스 요구사항을 갖는다. 하나의 컴포넌트는 CPU가 집중적으로 필요할 수도 있는 반면에 또 다른 컴포넌트는 메모리가 집중적으로 필요할 수 있다. 모놀리식 아키텍처는 각 컴포넌트 별로 독립적인 스케일 확보가 불가능하다.
  • 개발 스케일 확보의 장애물 – 또한 모놀리식 애플리케이션은 개발 스케일 확보에 장애물이다. 일단 애플리케이션이 특정 크기가 되면 엔지니어링 조직을 특정 기능 영역에 집중하는 팀으로 분배하는 것이 유익하다. 예를 들어, UI 팀, 회계 팀, 재고 팀 등으로 구분하기를 원할 수 있다. 팀들이 독립적으로 일하는 것을 막는다는 것이 모놀리식 아키텍처를 사용할 때의 문제점이다. 팀 간에 반드시 개발 노력과 재 배포를 조정해야만 한다. 이건 한 팀이 제품을 변경하고, 갱신하는 것보다 훨씬 더 어렵다.
  • 오랫동안 인정받은 기술 스택을 요구함 – 모놀리식 아키텍처는 개발을 시작했을 때 선택한 기술 스택(그리고 일부 경우에는 특정 기술의 정해진 버전으로)으로 강력히 강제한다. 모놀리식 애플리케이션에서는 새로운 기술을 적용하기 어려울 수 있다. 예를 들어, JVM을 선택해야 한다고 생각해보자. 지금까지 자바뿐만 아니라 몇 개의 언어를 사용하고 있고 그루비와 스칼라처럼 자바와 훌륭하게 상호 호환성(inter-operate)을 제공하는 다른 JVM 언어를 사용할 수 있다. 그러나 JVM 언어가 아닌 언어로 작성된 컴포넌트는 모놀리식 아키텍처에서는 존재할 수가 없다. 또한, 애플리케이션이 시간이 지나서 구식이 된 플랫폼 프레임워크를 사용한다면 새롭고 더 나은 프레임워크를 위해 애플리케이션을 점진적으로 마이그레이션 해야 하는 도전에 직면할 수 있다. 새로운 플랫폼 프레임워크를 적용하기 위해서는 전체 애플리케이션을 재작성 해야 하는 큰 위험을 책임져야만 가능하게 된다.

관련 패턴 #

마이크로서비스 아키텍처는 모놀리식 아키텍처의 제약을 다루는 대안 패턴이다.

쓰임새 #

Neflix, Amazon.com과 eBay처럼 잘 알려진 인터넷 서비스가 모두 최초에는 모놀리식 아키텍처였다. 대부분 웹 애플리케이션은 모놀리식 아키텍처를 바탕으로 개발되었다.