MSA
MSA (MircoService Architecture)
개념과 특성
마이크로 서비스 vs 모노리스
일반적으로 마이크로서비스는 모노리스와 비교한다.
두 아키텍쳐는 비즈니스를 구성하는 서비스의 단위로 구분할 수 있다. (차이점)
마이크로서비스
는 다양한 서비스의 조합으로 비즈니스를 구성하는 특징을 가지고 있고 모노리스
는 단일 서비스로 구성된다.
비즈니스 민첩성의 연장선
모노리스
방식으로 개발된 서비스들은 단일 개발환경에서 단일 데이터베이스에 모든 데이터를 저장하기 때문에 scale-out시 인스턴스의 규모가 커지고 작은 변화에서 빌드 및 배포시간이 커지는 단점을 가지고 있다.
이를 마이크로서비스
는 비즈니스를 작은 도메인으로 나누고 각 도메인에 따라 개발환경 및 데이터를 나눔으로써 scale-out시 인스턴스 규모가 작고 특정 도메인의 변화는 해당 서비스만 빌드 및 배포하면 되는 장점을 가지고 있다.
MSA 특징
MSA는 단순히 모노리스 아키텍처를 세분화해서 작은 단위의 서비스로 나누는것이 전부가 아니다.
설계적 관점뿐만 아니라 제품을 효율적으로 생산하는데 기반을 둔 조직문화도 고려해야한다.
다양한 기술스택을 가진 사람들이 모여 비즈니스의 빠른 의사결정과 개발 및 운영을 할 수 있도록 cross-functional 팀을 지향한다.
팀은 비즈니스의 전체 라이프사이클을 책임져야하기 때문에,
- 서비스 담당자와 소통이 수월한 개발 프로세스인 애자일을 활용하고,
- 개발외의 업무 부담을 줄이도록 배포 및 테스팅 프로세스를 자동화하는 devops 환경을 적극적으로 사용한다.
데이터 관점에서도 특징을 가지고 있다.
모노리스 아키텍처에서는 모든 데이터가 하나의 데이터베이스에서 관리되고 이를 하나의 트랜잭션으로 처리 할 수 있다.
MSA
에서는 Polyglot Persistence 접근 방법을 선택하여 서비스별로 나눠서 관리하고,
트랜젝션은 eventual transaction으로 서비스간 협업에 의하여 일시적으로 결과의 불일치가 있을 수 있지만, 결과적으로 데이터 일관성을 유지하는 방식을 취한다.
서비스간 통신은 간결한 방식으로 REST나 Message Queue를 사용한다.
서킷 브레이크 패턴과 같이 실패를 위한 설계를 하여, 더 이상 진행할 수 없는 환경에서도 대응할 수 있도록 하고
이를 위해 실시간 모니터링 체계를 갖추어야 한다.
MircoService outer/inner 아키텍처
소프트웨어 아키텍처
소프트웨어 아키텍처란, 소프트웨어를 구상하는 요소와 그 구성요소 간의 관계를 정의한 것 이다.
예를 들어, 성능, 가용성, 보안, 유지보수성, 확정성 등등 비기능적 요소들을 어떻게 고려하여 시스템을 구축할 것인가에 대한 정의로 볼 수 있다.
MSA는 클라우드라는 가상의 인프라를 활용하여 구조화 하기때문에 클라우드의 특징을 고려해서 설계해야한다.
클라우드를 고려했을 때 가장 중요한 요소는 바로 비즈니스의 변화에 대응할 수 있는 유연성
과 확장성
이다.
마이크로서비스 __ 아키텍처
마이크로서비스가 운영되는 환경을 정의하는 MSA outer architecture
와
실제로 비즈니스가 실행되는 각각의 마이크로 서비스 내 구조를 정의하는 MSA Inner Architecture
가 있다.
Microservice Outer Architecture
마이크로서비스가 운영되는 환경을 정의하는 것
인프라
MSA에서 인프라 환경은 클라우드 환경을 의미한다.
인프라 영역에 클라우드 사업자가 제공하는 IaaS를 선택할지, 기존 베어 메탈 장비나 가상머신인 VM을 선택할지 결정해야한다.
플랫폼
클라우드 사업자가 제공하는 PaaS를 선택할지, 직접 오픈소스로 프라이빗한 PaaS를 구축할지 결정해야한다.
먼저 가상 머신과 컨테이너 환경 중 적절한 것을 선택하고 오케스트레이션을 위한 제품을 선택하면된다.
오케스트레이션 : 컴퓨터 시스템과 애플리케이션, 서비스의 자동화된 설정, 관리, 조정을 의미
데브옵스 환경
Devops는 팀이 개발 및 운영에 책임을 가지는 상황에서 빌드 및 테스트, 배포 작업을 자동화하여 릴리즈 주기를 단축하고
배포사간을 단축하기 위한 일련의 과정이다. 보통 CI/CD 파이프라인을 구성
- CI (지속적통합)
개발자가 형상관리 툴에 코드를 MERGE하는 것을 시점으로 하여 빌드 및 정적 분석, 테스트, 배포 결과물까지 만드는 것 - CD (지속적제공)
배포 결과물을 운영 서버에 전달하거나, 서비스에 적용하는것
이러한 자동화 파이프라인을 어떤식으로 구성할지를 아키텍트가 정의하는 것이다
기반 서비스
- API Gateway
- BFF (Backend For Frontend)
- 서비스 디스커버리
- 컨피그 서비스
- 인증/인가 서비스
- Circuit breakeker
- Fallback
- Log Aggregation, Exception tracking
- Distributed Tracing
Microservice Inner Architecture
실제로 비즈니스가 실행되는 각각의 마이크로 서비스 내 구조를 정의하는 것
Application Architecture
Application Architecture를 표현하는 방식에 있어 대표적으로 Layered Architecture(계층형 아키첵쳐)가 존재한다.
Layered Architecture (계층형 아키텍처)
Layer간에 인터페이스로 호출함으로써 요청 규약을 명확히 정의하여 개발 효율성을 높이고 로직의 변경 및 확장을 용이하게 해주는 구조이다.
하지만 layer간 인터페이스가 일방향에 의존하기 때문에 의존하는 층에 영향을 받을 수 밖에 없다.
이런한 단점을 해결하는 방안이 Hexagonal Architecture
이다.
Hexagonal Architecture
사용자 인터페이스나 저장소가 변경이 되어도 구현 처리를 하는 층이 그 차이점을 흡수해서 Business Logic 층이 영향이 없게 하는 구조를 말한다.
Layered 와 Hexagonal Architecture를 활용하여 마이크로서비스의 각 layer를 어떻게 구조화해야되는지 알아보자
- Persentation Layer
Persentation Layer에서 가장 많이 사용되는 것은 MVC 패턴이다.
마이크로서비스로 설계되면서 Front-End Microservice 구조를 가져가는데, Front End를 구성하는 UI 컴포넌트도 독립적으로 분해되면서
Server-side Page Fragment Composition 방식으로 발전된다. - Business Logic Layer
Transaction Script 패턴과 Domain Model 패턴이 많이 언급된다.
Transaction Script 패턴 구조는 단순한 입출력 구조의 쉬운 업무 처리를 위한 마이크로 서비스 내부 구조로 활용하면 유용하다.
하지만 복잡한 비즈니스 로직을 잘 정리하여 핵심 서비스로 활용해야 할 경우에는 Domain Model 패턴 구조의 마이크로서비스 내부 구조를 취하면 효율적이다. - Data Access Layer
Hexagonal Architecture가 적용하여 어떤 저장소가 오더라도 Business Logic 층에 영향을 적게 받도록 하는 것이 중요하다.
일반적으로- Bussiness Logic 층이 Transaction Script 구조로 설계된 경우 SQL Mapper를 선택, 데이터 모델링을 먼저 수행하는 방식으로 진행을 하고
- Bussiness Logic 층이 Domain Model 구조로 설계된 경우에는 OR Mapper를 선택, 도메인 객체 모델링을 먼저 수행하는 방식으로 진행한다.
Event Driven Architecture
Microservice간 호출하는 방식은 동기식 방식과 비동기식 방식으로 구분할 수 있다.
RestAPI와 같은 인터페이스를 활용한 동기식 방식은 구현이 쉽다는 장점이 있지만, 특정 서비스의 장애가 다른 서비스의 장애로 전파될 위험을 가지고 있어 MSA에서는 적합하지 않다.
따라서 MSA에서는 Microservice간 이벤트를 전달하고 요청을 종료하는 비동기식 방식을 사용한다.
이벤트 전달을 위한 매개체로는 Apache Kafka, RabbitMQ, ActiveMQ와 같은 메시지 브로커를 사용한다.
SAGA Pattern
Command Query Responsibility Segregation(CQRS) Pattern
Event Sourcin Pattern
Domain Driven Design (도메인 주도 설계)
Domain도메인
이란, 비즈니스나 현실세계의 복잡한 문제를 의미한다.도메인 주도 설계
란, 도메인의 가치를 최우선시하는 모델링 기법으로 크고 복잡한 도메인을 이해하고 탐구하는 활동을하고, 이를 통해 발견된 다양하고 많은 도메인의 문제들을 해결하기 위한 소프트웨어 개발의 철학이라고 할 수 있다.
코드를 구현하기에 앞서 도메인과 모델을 명확하고 완전한 이해를 강조한다.
이러한 활동을 통해 비즈니스의 중요도에 따라 서비스 경계를 설정하고 개발함으로 인해서 코드의 응집도를 높여 가독성이나 유지보수성을 높일 수 있다.
도메인 주도 설계에서는 마이크로서비스를 식별하는 전략적설계
와 식별된 마이크로서비스의 내부 구조를 상세하게 설계하는 전술적 설계
를 할 수 있다.
전략적 설계
마이크로서비스를 식별하는 과정
제품 책임자와 도메인 전문가, 개발자 혹은 각 조직별로 사용하는 언어를 일치시키기 위한 유비쿼터스 언어를 정의하는것이 중요하며, 서브 도메인(핵심, 지원, 일발)을 구분하고, 이를 바탕으로 Bounded Context
를 정의하는것이 중요하다.
Bounded Context로 분할하게 되면 각 Bounded Context간에 의사소통이 반드시 필요하게 된다.
때문에 Bounded Context간 의사소통을 위해 관계를 찾아 통합하는 컨텍스트 매핑이 필요하게되고 아래와 같이 정의된다.
- 공유 커널(Share Kernal) : Bounded Context 사이에 공통적인 모델을 공유하는 관계
- 고객공급자 유형(Cutstomer-Supplier) : 고객이 원하는 것을 공급자가 제공해 주는 관계
- 준수자 유형(Confomist) : 공급자의 모델을 그대로 따르는 방식의 관계
- 충돌 방지계층(Anti-Corruption Layer) : 공급자와 모델과 고객 모델 사이에 번역 계층을 만드는 방법
- 공개 호스트 서비스(Open Host Service) : Bounded Context에 접근할 수 있는 인터페이스를 정의하는 방법
- 발행된 언어(Publiched Language) : Bounded Context의 규모와 상관업이 사용과 번역을 가능하게 하는 문서화된 정보교환언어를 제공하는 방법
전술적 설계
전술적 설계는 마이크로서비스(바운디드 컨텍스트로 식별된)의 내부 구조를 상세하게 설계하는 단계이다.
따라서 다이어그램을 활용하여 마이크로서비스의 내부를 설계하고 각 마이크로서비스간의 관계를 표현하게 되는데.
이렇게 다이어그램과 같은 도메인 모델을 그리기 위해 알아야 될 도메인 모델의 표준 패턴을 보면 다음과 같다.
- 계층형 아키텍처(Layered Architecture) : 도메인 주도 설계에서는 도메인 계층을 분리하는 것이 매우 중요하다.
- 엔티티(Entity) : 고유한 식별자이면서 변화 가능성이 있는 객체
- 값 객체(Value Object) : 개념적으로 식별성이 없고, 단순히 값만을 갖고 있는 객체
- 표준 타입(Standard Type) : 대상의 타입을 나타내는 서술적 객체
- 애그리게잇(Aggregate) : 업무상 관련 있는 객체들을 모아 경계를 명확히 정의하는 패턴
- 저장소(Repository) : 애그리게잇의 개념적인 저장소
- 도메인 이벤트(Domain Event) : 하나의 마이크로서비스 내부의 변경이 다른 마이크로서비스로 파생되는 작업이 필요한 경우 사용
도메인 모델의 표준 패턴은 다음 세 단계의 설계절차를 통하여 식별할 수 있게 된다.
- 도메인 모델 설계 : 엔티티와 값 객체, 표준 타입을 식별하고 애그리게잇을 식별
- 도메인 모듈 설계 : 서비스 인터페이스와 저장소 인터페이스를 정의
- 마이크로서비스 설계 : 각 마이크로 서비스의 동기/비동기 연동을 설계
| reference