DDD와 MSA #2

DeokwonPark·2022년 11월 27일
1
post-thumbnail

3. 마이크로서비스 애플리케이션 아키텍처

마이크로서비스 애플리케이션은 초기 개발뿐만 아니라 지속적인 비즈니스 변화에 빠르게 대응 할 수 있는 구조 설계가 필요하다.
그렇지 못한 경우 비즈니스 수정이 발생했을 때 파급효과 및 영향도를 알 수 없어 실제 변경작업보다 다른 모듈의 영향도를 파악하기 위한 테스트에 더 많은 시간을 투자해야 할 수 있다.

1) 비즈니스 로직은 어디에? - 관심사의 분리

관심별로 관련된 기능을 모아 독립된 모듈로 만들어 다른 코드로 부터 영향도를 낮추는 원칙이다. 이것을 통해 시스템을 이해하고 변경하기 쉽게 만들어진다. 또한 비즈니스 로직과 기술영역을 구분하는 것이 좋은데 이는 오랫동안 안정되어야하는 비즈니스 로직이 빠르게 변화하는 기술영역에 영향을 받으면 좋지 않기 때문이다.

데이터베이스 중심 아키텍처의 문제점

특정 관계형 데이테베이스 물리테이블 모델을 중심으로 애플리케이션을 구현하려는 사고방식이다.

Service에는 흐름제어 로직만 존재할 뿐 대부분의 비즈니스 개념들과 규칙들은 SQL질의에 존재하게 된다. 따라서 대부분의 성능이 데이터베이스에 의존하게 되어 유연하지 못하고 애플리케이션 스케일 아웃시 이점을 얻을 수 없어 좋지 못하다.


2) 헥사고날 아키텍처와 클린 아키텍처

마이크로서비스의 내부구조를 유연하게 하기 위한 다양한 아키텍처

레이어드 아키텍처

레이어드 아키텍처를 구성하는 각 레이어는 물리적인 레벨이 아닌 논리적인 레벨의 개념이다.
애플리케이션 내부 관심사를 프레젠테이션(화면표현 및 전환), 비즈니스 로직, 데이터 엑세스 3개의 논리적인 계층으로 구분한다.

각 레이어간 응집도를 높이고 의존도를 낮추기 위해 다음과 같은 몇가지 규칙을 둔다.

  • 상위계층이 하위계층을 호출하는 단방향성을 유지한다.
  • 상위계층은 모든 하위계층을 알 필요 없이 바로 아래계층만 활용한다.
  • 상위계층은 하위계층에 영향을 받지 않게 구성해야한다.
  • 하위계층은 자신을 사용하는 상위계층을 알지 못하게 구성해야한다.
  • 계층간 호출은 직접 의존하지 못하도록 인터페이스를 통해 호출하는것이 바람직하다.

DIP(의존성 역전 원칙)
상위계층이 하위계층의 구체에 의존하는것이 아닌 인터페이스에 의존하여 원칙을 만족하는 것처럼 보인다.

OCP(개방폐쇠원칙) - 개체는 확장에는 열려 있어야 하며 변경에는 닫혀 있어야한다.
레이어드 아키텍처는 상위계층이 하위계층의 인터페이스에 의존하게 되는데 이때 상위계층이 의존하는 인터페이스는 하위계층이 정의 하므로 하위계층의 인터페이스가 확장되었을때 상위계층은 변경이 불가피하므로 OCP원칙을 위배하게 된다.

따라서 하위계층의 인터페이스를 상위계층에서 정의하여 원칙을 만족시킨다.

헥사고날 아키텍처

레이어드 아키텍처의 단방향 계층구조로는 다양한 시스템과 상호작용하는 애플리케이션을 지원하기 힘들다는 문제가 있다. 다방면으로 개방된 핵사고날 아키텍처는 이러한 문제점을 해결할수있다.


헥사고날 아키텍처는 고수준의 비즈니스 로직을 처리하는 내부영역과 저수준의 외부영역으로 구분하여 구성된다.

클린 아키텍처

헥사고날 아키텍처와 매우 유사한 아이디어이며, 크게 중앙의 엔티티, 유스케이스, 그외의 세부사항으로 구분된다.

  • 엔티티 : 업무의 핵심규칙과 핵심규칙이 필요한 데이터를 결합한 객체
  • 유스케이스 : 엔티티 내부의 핵심 업무규칙을 호출하여 사용하는 시스템 흐름
  • 세부사항 : 입출력장치, 통신 프로토콜, 서버, 프레임워크 등과 같은 나머지 모든 영역

3) 마이크로서비스의 내부구조 정의

마이크로서비스 내부구조를 정의할때 반드시 고려해야 할 사항은 시스템에서 정의해야할 내부구조가 다양할 수 있다는 것이다.(서비스 별로 다양한 언어, 저장소 아키텍처를 가질 수 있음)

고수준의 영역은 저수준의 영역에 의존하지 않게 하며, 저수준 영역은 언제든 확장이이 가능해야하며 이는 고수준의 영역에 영향을 줘서는 안된다.

도메인 - 핵심 비즈니스 개념과 규칙을 구현
서비스 - 도메인을 호출하여 처리절차를 기술하며 외부영역 연계 인터페이스를 제공한다.
리포지토리 인터페이스와 같이 외부영역 인터페이스를 내부영역에서 구현하고 추상화하여 외부영역의 각 저장소에 맞게 세부기술로 구현한다.

트랜잭션 스크립트 패턴 (내부영역)


비즈니스 개념을 표현하는 도메인 객체는 행위를 가지지 않고 수행하는 책임은 서비스에게 있다. 서비스가 비즈니스 절차에 따라 도메인 객체를 이용해 모든 처리를 수행한다.
대부분의 비즈니스 로직 처리가 서비스에서 이루어지기 때문에 중복되는 코드가 계속 생겨날 수 있다.

도메인 모델 패턴 (내부영역)

도메인 객체가 데이터 뿐만아니라 비즈니스 행위를 가지고 서비스의 행위를 일부분 도메인 객체에 위임해서 처리한다. 따라서 서비스의 책임들이 각 도메인으로 적절히 분산되기 때문에 복잡한 비즈니스 로직을 처리하는데 유용하다.

애그리거트 패턴 (내부영역)

도메인 모델링시 객체간의 참조 관계가 복잡하고 무거워질 수 있는 단점을 보완한 패턴이다.

최상위 루트 엔티티를 중심으로 개념의 집합(애그리거트)을 분리한다.

  • 애그리거트 루트만 참조한다. (상세클래스 직접참조X)
  • 애그리거트간 참조는 기본키를 통해서 한다.(느슨하게 연관되어 실수를 방지)
  • 하나의 트랜잭션으로는 하나의 애그리거트만 생성 및 수정한다.

0개의 댓글