
adjective
1. formed of a single large block of stone.
"later Byzantine columns were monolithic and usually made of marble"
2. (of an organization or system) large, powerful, and intractably indivisible and uniform.
"rejecting any move toward a monolithic European superstate"From: Oxford Languages
보다 세부적인 사항을 들어가기에 앞서, 우선 모놀리식 아키텍처를 살펴보자.

각 개발 부서는 DevOps 패턴에 맞춰 CI/CD를 구성하고 테스트, 배포 등을 지속적으로 수행하게 된다. 이렇게 구성되었을때 각 개발 부서는 하나 이상의 하위 도메인을 담당하며 개발/운영을 담당하게 된다. 이때 하위 도메인은 비즈니스 기능의 일부를 구현하는 범위로, 일반적으로 DDD(Domain Driven Design)패턴에 따라 내부 업무 및 외부와 소통하는 인터페이스(어댑터)로 구성되게 된다. 그림에서는 고객(consumer)과, 주문(order), 그리고 배달 관리(delivery management)로 역할이 구분되며, DevOps 팀도 그에 맞춰서 구분되어 있다. 추가로 배달관리 업무는 배달에 대한 관리와, 실제 배달을 수행하는 courier에 대한 관리 기능으로 나눌 수 있으나 하나로 통합되어 구성되어 있고, 각 팀은 자신의 domain에 대한 개발과 운영의 책임을 지게 된다. 일반적으로 각각의 하위 domain이 하나의 기둥(monoloth)을 구성하고, 각 하위 도메인은 java의 JAR/WAR로 컴파일된 클래스 패키지 형태로 구성한다.
Microservice Pattern 의 저자, Richard Stevensen은 아키텍처를 구성하는데 영향을 주는 것을 천문학(천체물리학)에서 말하는 암흑물질(dark matter)와 암흑에너지(dark energy)를 기반으로 설명한다.
암흑 물질(暗黑物質, dark matter)은 우주 물질의 약 85%를 차지하는 것으로 생각되는 물질의 가설상의 형태이다. 암흑 물질은 전자기장과 상호 작용하지 않는 것처럼 보이기 때문에 "암흑"이라고 불리는데 , 이는 전자기파를 흡수, 반사 또는 방출하지 않으므로 탐지하기 어렵다는 것을 의미한다. 다양한 천체물리학적 관측들, 즉 만일 볼 수 있는 것보다 더 많은 물질이 존재하지 않는다면 현재 받아들여지고 있는 중력 이론으로는 설명할 수 없는 중력적 효과를 포함하는 관측들은 암흑 물질의 존재를 암시한다.
From: Wikipedia
물리 우주론과 천문학에서, 암흑 에너지(Dark energy)는 우주에 가장 큰 규모로 영향을 미치는 알려지지 않은 에너지 형태이다. ... 암흑 에너지는 매우 균질하고 밀도가 매우 높지는 않은 것으로 생각되며, 중력 이외의 기본 상호작용들을 통해 상호 작용하지 않는 것으로 알려져 있지 않다. 매우 희귀하고 질량이 크지 않기 때문에―약 10-27kg/m3―그것이 실험실 실험에서 탐지될 수 없을 것이다. 암흑 에너지가, 우주 밀도의 68%를 차지할 정도로 희박하면서도 우주에 엄청난 영향을 미칠 수 있는 이유는, 암흑 에너지가 빈 공간을 균일하게 채우기 때문이다.
From: Wikipedia
애플리케이션 아키텍처 설계에서의 암흑 에너지는 마이크로서비스를 더 작고 독립적으로 만들려는 추진력으로, 각 서비스가 자율적이고 독립적으로 운영될 수 있으며, 팀 간의 의존성을 최소화하려는 목표를 만들게 하는 것을 의미한다. 반면 암흑 물질은 서비스 분리를 방해하는 힘으로 서비스가 단순하고 효율적으로 통신할 수 있도록 하려는 힘이며, 이는 지나치게 많은 서비스로 분할되는 것을 막는 역할을 하는 힘이다. 이 두 힘의 균형을 맞추는 것이 아키텍처 설계에서 중요하다.
암흑물질 및 암흑 에너지와 관련된 보다 세부적인 사항에 들어가기 앞서, 일반적으로 애플리케이션의 아키텍처를 설계할 때는 드음 질문 들에 대하여 먼저 살펴보자.
시스템의 운영과 서브도메인은 애플리케이션의 기능을 구현하기 위한 단위 모델이다.(An application’s system operations and subdomains are an implementable model of its functionality.)
시스템 운영(system operation)이란, 애플리케이션의 기능적 요구사항들을 정제한 것으로, 애플리케이션이 처리해야 하는 요구사항(아직은 정제되지 않은, 고객입장에서 지금 배달이 가능한 식당을 찾아 - 지금 주문이 가능한 식당을 찾거나, 배달이 가능한 거리의 식당을 찾는 등의 요구사항이나, 식당 입장에서 지금 만들 수 있는 주문을 받거나, 받은 주문을 배송하기 위한 배달업체를 찾는 등의 세부 요구사항들이 도출)들을 추상화, 모델링 한 것이다. FTGO(Microservice pattern의 가상의 배달 주문 애플리케이션)에는 기준으로 보면, createOrder(), cancelOrder(), acceptOrder(), findOrderHistory() 와 같은 기능으로 구현되게 된다. 시스템 운영들은 기능의 나열이 아니라 시간의 흐름, 이벤트에 따라 트리거 되는 절차(고객의 주문 생성 -> 식당의 주문 수락 -> 배달 대행 수배 -> 주문 완성 및 배달 요청 등)도 같이 모델링하게 된다.
따라서 애플리케이션의 설계에는 기능적 요구 사항(고객은... 식당 주인은...) 을 시스템 운영으로 정제하는 것에서 시작된다. 결과적으로, 시스템 운영으로의 정제는 애플리케이션의 설계 프로세스의 중심적인 역할을 하게 된다.
애플리케이션의 기능은 시스템 운영으로 모델링되고, 모델링된 내역은 하위 도메인으로 분리되어 각각 구현된다. 하위 도메인은 (일반적으로) 개발과 운영을 담당하는 소규모의 팀이 소유하는 형태로 구현 가능한 비즈니스 역량의 객체 지향 모델이 된다. 예를 들어, FTGO 애플리케이션에는 Order Management, Delivery Management, Restaurant Management, Kitchen Management 등의 하위 도메인을 만들고, Java로 구성한다고 가정하면 각 하위 도메인은 클래스를 포함하는 Java 패키지가 된다.
각 시스템 운영은 하나 이상의 하위 도메인에 걸쳐서 동작하게 된다. 예를 들어 createOrder()의 시스템 운영은 Order Management, Restaurant Management, Kitchen Management, Accounting 등 여러 도메인에 걸처 작동하게 된다. 애플리케이션의 하위 도메인은 아키텍처의 논리적(일명 개발) 뷰와 실행 가능/배포 가능한 단위인 구성 요소로 패키징되는 방식을 정의하는 구현 뷰(implementation view)를 구성한다.
구현 뷰는 애플리케이션의 모듈(서브 도메인으로 컴파일되고 패키징 되는)과 컴포넌트(실행가능하거나, 혹은 배포 가능한 하나 이상의 모듈의 집합)를 정의하는 것으로, 모듈은 일반적으로 JAR 파일로 패키징되고, 콤포넌트는 WAR 파일 또는 실행가능한 대규모(fat) JAR 파일(여러 JAR를 모은)로 구성된다.
만약 애플리케이션이 하나의 컴포턴트로 구성되어 있으면 monolithic architecture이고, 2개 이상의 컴포넌트로 구성되면 microservice architecture로 정의할 수 있다. (If an application consists of a single component then it has a monolithic architecture. Alternatively, if it consists of two or more components then it has a microservice architecture.)
이제, 위의 정의를 기반으로 문제를 정의해 보자.
1. 하위 도메인을 하나 이상의 서비스(구성 요소)로 어떻게 분할할 것인가? 예를 들어, 세 개의 하위 도메인 A, B, C가 있을 때, 이를 ABC; AB + C; A + B + C 등 다양한 방식으로 분할할 수 있는데, 어떤 선택이 합리적인 것일까?
2. 여러 서비스에 걸친 시스템 운영을 어떻게 설계할 것인가?
이 두 문제는 상호 연관되어 있으며, 적절한 분할이 시스템 운영의 효율적인 구현을 방해할 수 있으므로 분할에 대하여 재설계가 필요할 수 있다. "암흑 에너지"와 "암흑 물질"의 비유는 이러한 문제 해결에 도움이 되는 개념이다.
아래 그림은 암흑에너지와 암흑물질을 설명하는 것으로, 각 5개의 암흑에너지에 의한 척력과 5개의 암흑물질에 의한 인력으로 구성되어 있다.
천체물리학자들은 우주의 팽창이 이전에는 감속되고 있었으나 70억 년 전부터 가속화되기 시작한 이유를 설명하기 위해 암흑 에너지의 개념을 발명했다. 암흑에너지 이론에 따르면 우주가 팽창함에 따라 중력이 약해졌고, 결국 척력인 암흑 에너지가 우세해져 팽창을 가속화했다고 합니다. 암흑 에너지는 서브도메인을 여러 서비스로 분할하도록 장려하는 척력을 설명하는 유용한 은유, 각 서브도메인에 작용하여 서브도메인을 여러 서비스로 분할하도록 장려하는 다섯 가지 암흑 에너지에 의한 힘은 다음과 같다.
천체물리학자들이 먼 은하의 별들의 궤도를 관찰했을 때, 그들은 별들이 가시적 물질의 양에 기반한 예상보다 더 빠르게 움직인다는 것을 발견했고, 이 불일치를 설명하기 위해, 인력을 발휘하는 보이지 않는 형태의 물질인 암흑 물질의 개념을 발명했다. 이는 마이크로서비스 아키텍처에서 서비스로의 분해를 저항하는 인력을 설명하는 유용한 은유로, 서브도메인에 작용하는 인력은 그 서브도메인들을 걸쳐 있는 시스템 작업에 의해 생성되게 된다. 서비스의 분해를 저항하는 데는 다음의 다섯 가지 암흑 물질에 따른 인력이 있다.
모놀리식 아키텍처가 매력적인 한 가지 이유는 모든 인력의 필요성을 만족시키기 때문이지만, 안타깝게도 특히 애플리케이션이 큰 경우에는 모든 척력을 무시하게 되는 문제가 발생한다. 반대로, 세분화된 마이크로서비스 아키텍처는 모든 척력을 만족시키지만 인력을 무시하게 되는 문제가 발생하여 과도한 설계 시간 및 런타임 결합으로 인해 두 아키텍처 스타일의 최악의 면을 결합한 취약한 분산 모놀리스가 될 수도 있다. 따라서 아키텍트의 임무는 구성요소 내의 척력을 최소화하고 동시에 구성요소 간의 인력을 최소화하는 아키텍처를 설계하는 것이다.
모놀리식 아키텍처(monolithic architecture)는 소프트웨어 개발 및 시스템 설계의 한 형태로, 전체 어플리케이션을 단일한 코드 베이스로 구축하는 방식이다. 이는 전통적인 웹 애플리케이션 구축 방식에서 일반적으로 찾아볼 수 있으며, 모든 기능과 모듈이 하나의 실행 파일 안에 포함되어 있는 형태를 의미한다.

모놀리식 아키텍처에 대하여 더 논의 하기 이전에, Microservier Pattern의 책에서 논의하는 가상의 회사인 FTGO에 대해서 먼저 살펴보자. FTGO는 다음 그림과 같은 구조의 모놀리식 구조에서 시작한다. FTGO는 REST API와 Web UI 어댑터를 사용하여 외부 고객의 요청을 수용, 응답하며, 어플리케이션은 내부적으로 각종 비즈니스 로직을 처리하고, MySQL 어댑터를 통해 DB에 저장하거나, 다른 외부의 클라우드서비스를 호출해주는 어댑터를 통해 호출하는 등의 역할을 보여준다.
FTGO는 하나의 소스코드 저장소에 모듈을 저장하며, 모든 모듈이 통합된 하나의 WAR파일을 실제 어플리케이션으로 구동하여 서비스를 운영하는 형태로, 각 모듈과 관련된 코드들은 하나의 패키지로 구성되어 확인 및 새로운 기능을 구현, 기존 코드를 전부 분석하기는 것에 상호 연관성이 있어 쉽지 않은 산태가 된다. 또한 대규모 소스 코드를 각 개발자의 PC에서 실행시켜야 하기 때문에 IDE의 실행속도나, 빌드시간 등의 생산성 문제를 가져오게 된다. 또한 모듈간의 복잡한 코드들을 전부 통합하여 한번에 릴리즈를 하기에는 소스병합이나 테스트를 지속해서 진행해야 하며, 작은 변경에 전체 기능 테스트를 해야 하는 문제등이 발생하게 된다. 더욱이 하나의 어플리케이션으로 구동하기 때문에 확장성도 떨어지며, 모듈들중 하나의 어플리케이션이라도 문제가 생긴다면 전체 어플리케이션에 영향을 미치고, 프로젝트 초기에 결정된 기술을 그대로 따를 수 밖에 없어 버전업이나 기술스택을 변경하는 일이 쉽지 않은 문제를 가지고 있다.

애플리케이션의 확장 관련하여 저자는 The Art of Scalability(Michael T.Fisher, Martin L. Abbott, Addison-Wesley Professional, 2009)에서 제안한 인스턴스의 수, 파티션의 수 및 서비스의 수로 분리되는 3축 방향의 확장 전략을 소개하고 있다. 참고로 scalability에서는 scale up은 그 한계가 명확하므로 주요 고려 대상이 되지 않는다.
| 구분 | 내용 | 상세 |
|---|---|---|
| X축 | 다중 인스턴스로의 확장 | X축 확장은 로드밸런서 등을 통해 동일한 요청을 처리하는 복수의 인스턴스들에게 분배하여 어플리케이션들의 가용성과 성능을 높이는 방법 |
| Z축 | 데이터의 파티셔닝 | X축 확장은 인스턴스 단위로 동일한 요청을 처리하는 복수의 인스턴스 간 부하를 분산시키는 것과 달리, 분산 이전에 라우터 등을 통해서 처리해야 할 인스턴스 별 업무 범위(지역, ID의 분포 등)를 분배하여 트랜잭션이나 데이터볼륨을 처리하기 위한 확장 방법. 지역기반 라우팅 등을 포함 |
| Y축 | 기능에 따른 서비스 분해 | X축과 Z축은 애플리케이션의 성능과 가용성을 높였지만 각 인스턴스는 동일한 업무를 처리해야 하기 때문에 애플리케이션의 복잡성은 해결이 어려움. Y축 확장은 복잡한 플리케이션을 여러 서비스로 나누어 개발/유지보수의 복잡성을 해결하는 방안으로의 확장 |
각 확장 방향을 도식화 하면 다음과 같다.
| 구분 | 이미지 |
|---|---|
| X축 확장 | X-axis scaling runs multiple, identical instances of the monolithic application behind a load balancer. |
| Z축 확장 | Z-axis scaling runs multiple identical instances of the monolithic application behind a router, which routes based on a request attribute . Each instance is responsible for a subset of the data. |
| Z축 확장 | Y-axis scaling splits the application into a set of services. Each service is responsible for a particular function. A service is scaled using X-axis scaling and, possibly, Z-axis scaling. |
X축과 Z축은 monolithic architecture에서도 적극 사용되고 있는 방안이며, Microservice architecture에서는 Z축의 확장인 Order Service, Customer Service, Review Service 등의 서비스 단위로 분리한 Y축의 역할이다. 더욱이 이 요청은 단순히 Y축으로의 확장에 멈추는 것이 아니라, 서비스의 요청은 로드밸런서 등을 통한 X축 확장과, 지역별 분배 등을 통한 Z축의 확장도 동시에 수용할 수 있는 구조가 된다. 즉, 마이크로서비스 아키텍처는 하나의 어플리케이션을 큰 하나의 서비스가 아닌, 조금은 작게 나뉘어질 수 있는 여러 서비스로 기능을 분해하고, 각각의 분해된 기능간 통신, 트랜잭션 관리를 통해 비즈니스를 달성시키고자 하는 아키텍처 스타일이다.
갈수록 애플리케이션들은 규모가 확대되고 있으며, 내용이 복잡해서 모듈 단위로 분해하여 개발하게 된다. 따라서 기존의 모놀리식으로 배포되는 자바 패키지나 JAR를 조합한 단위로 모듈을 정의하는 문제는 각 모듈간 버전이나 디팬던시와 같은 문제가 지속 발생되며, 상호 연관성에 의해 유지보수가 어려워지고 있다. 이러한 문제를 해결하기 위해, MSA는 하나의 서비스를 모듈의 단위로 사용하고, 각 서비스가 다른 서비스의 데이터(즉, DB schema나 file 등)에 직접 접근하는 혼잡석을 차단하고, 공개(내부든, 외부든)된 API를 통해서만 각 서비스간 데이터, 요청에 접근할 수 있게하는 것이 핵심이다. 따라서 시간이 지나더라도 각자의 모듈은 API만 유지시키고 내부는 개별적으로 고도화가 가능하므로 독립적으로 유지/보수가 수월하게 되며, 배포/확장도 API 명세를 유지하는 선에서 진행이 가능하게 된다.
각각의 서비스는 각각 자체 DB를 가지기 때문에 런타임시 DB락과 같은 서비스 블로킹이 발생하지 않는다. 개별 서비스가 각각의 DB를 갖는다는 것이 자체 DBMS를 설치/유지해야 한다는 것과 동의어는 아님에 주의할 필요가 있다.
다음 그림은 FTGO 애플리케이션을 Y축으로 확장(기능별로 분해된 frontend/backend 서비스)하여 개별 서비스로 분해한 형상이다. Frontend 서비스로는 소비자나 배달원의 애플리케이션(Mobile, PC, App)에서의 API의 호출을 처리하는 API Gateway와 Restaurant의 관리자가 메뉴를 관리하거나, 주문에 대한 처리를 수행하는 Web UI를 제공하는 서비스가 있을 수있다. Backend 서비스로는 private 저장소(local DB 등)을 가진 다양한 서비스(주문, 음식점, 주방, 배달, 회계, 알림 등)로 구성된다.
마이크로스비스 아키텍처는 SOA와 별반 다를 것이 없다라는 말들이 있다고 한다. 고수준에서 바라보면 두 방식 모두 시스템을 여러 서비스로 분할 구성하는 아키텍처 스타일로 유사할 수 있다. 그러나 보다 세분화해서 살펴보면 다음과 같은 차이를 확인할 수 있다.
| 구분 | SOA | Microservice |
|---|---|---|
| 서비스간 통신 | SOAP, WS* 표준처럼 무거운 프로토콜을 응용한 엔터프라이즈 서비스 버스 중심의 스마트 파이프(smart pipe) | REST나 gRPC처럼 가벼운 프로토콜을 응용한 메시지 브로커 또는 서비스간 통신 중심의 덤 파이프(dump pipe) |
| 데이터 | 전역 데이터 모델 및 공유 DB | 서비스 개별 데이터 모델 및 DB |
| 주요 사례 | 대규모 모놀리식 애플리케이션 | 소규모 서비스 |
애플리케이션의 아키텍철를 논의하기 위해서 용어 및 언어 사용은 중요한 문제가 된다. 따라서 저자는 technology(기술)를 객관적으로 describe(설명, 기술) 하기 위한 방법으로 패턴과 패턴언어를 제시하고 있다. 패턴은 어떠한 문제를 풀기 위한 방법이고, 이러한 패턴을 기술하기 위해서는 문제를 정의하고, 문제가 해결 가능한 환경을 설명하며, 어떤 형태로 문제를 해결했다는 등의 내용을 모두 기술한다.

다만 패턴언어 자체는 개념을 공부한 이후에 추가로 학습해도 좋을 듯 하다.