[아키텍처] 계층형 아키텍처와 MSA 본문

백앤드 개발일지/스프링부트

[아키텍처] 계층형 아키텍처와 MSA

giron 2022. 2. 11. 10:55
728x90

계층형 아키텍처(Layered Architecture) or 멀티 티어(tier) 아키텍처

- 책임과 성격이 다른 것을 크게 그룹으로 만들어 분리해두는 것

- 유사한 관심사들을 layer로 나눠서 수직적으로 배열한 것

 

보통 웹 기반의 엔터프라이즈 애플리케이션은 3개의 계층을 갖는다고 해서 3계층 애플리케이션이라고도 한다.

 

3계층 아키텍처와 수직 계층(토비의 스프링)

Presentation Layer: 웹 기반의 UI를 만들어내고 그 흐름을 관리하는 계층

Service Layer: 비즈니스 로직을 담고 있는 계층

DataAccess Layer: 백엔드의 DB나 레거시 시스템과 연동하는 인터페이스 역할을 하는 계층(infrastructure 계층)

토비의 스프링

3계층 아키텍처(조영호 개발자님)

Presentation: 화면 조작, 사용자의 입력 처리를 위한 계층

Domain: 비즈니스와 관련된 도메인 로직 처리, 도메인을 조작하기 위한 모든 것

Data Source: DB와 관련된 계층 ex) RDB

 

검색해볼때마다 3계층 아키텍처의 각 계층을 부르는 이름들이 다양했는데 모두 기억해두라고 한다.

 

장점

  • 중간에 구조를 바꿀때 그 부분만 바꾸면 된다.(전체를 손댈 필요가 없다.)

 

객체가 있고 여기에 필요한 메서드가 있다고 접근하는게 아닌 요구사항을 수행하기에 적절한 객체에 책임을 할당한다. (creator 패턴)

요구사항 -> 객체 로 할당해간다.

 

객체지향적인 코드는 서로 협력관계를 통해 관계를 맺는다.

즉, 적절한 객체한테 책임을 위임하고 객체들간의 협력관계를 통해 풀어가는 것이다.

 

도메인 모델을 구성할때는 service layer를 두는것이 바람직하다.

Service layer

-  서비스레이어를 도메인 레이어 위에 만들어서 도메인 레이어에 침투하지 않게하여 어플리케이션 로직을 처리함. 어플리케이션 로직마다 서비스 레이어를 만들면 도메인 로직의 재사용이 가능해진다.

1. 어플리케이션 경계

2. 도메인로직 재사용

3. 트랜잭션 바운더리를 결정

객체지향 - 도메인 모델 vs 절차지향 - 트랜직션 스크립트

도메인 모델과 트랜잭션 스크립트

 

 

이외에 흔히 접할 아키텍처

프레젠테이션 층

  • 입력된 값을 바다 값을 확인하거나 값의 변환을 실시하는 층 
  • ex) Controller 클래스

애플리케이션 층

  • 애플리케이션 층은 프레젠테이션 층에서 받은 값을 도메인 층에 전달하는 층
  • 비즈니스 로직은 포함하지 않지만 화면 전환을 제어하거나 세션을 사용하면 다음 화면에 값을 전달한다.
  • ex) Service 클래스

도메인 층

  • 도메인 객체를 가지고 비즈니스 로직을 처리하는 메인 층
  • 도메인 객체는 모든 계층에서 사용되지만, 도메인층은 다른 계층에 의존해서는 안 된다.
  • ex) Domain 클래스

인프라스트럭처 층

  • 도메인 계층에서 전달된 데이터를 영속화하는 층
  • 애플리케이션 계층의 영향을 받지 않도록 설정해야 한다.
  • ex) JpaRepository 클래스

MSA(MicroService Architecture)

대표적으로 외부 api를 호출하는 방식에 resttemplate이 있는데 이것은 동기 방식을 이용한 방법이고, WebClient가 비동기를 이용한 방식이다. 공식문서를 보면 스프링5부터는 webClient사용을 더 추천하고 있다. 공통점으로는 둘다 Http client에서 사용된다는 것이다.

 

RestTemplate

RestTemplate은 Multi-Thread와 Blocking방식을 사용합니다. 

Thread pool은 요청자 어플리케이션 구동시에 미리 만들어 놓습니다.

Request는 먼저 Queue에 쌓이고 가용한 스레드가 있으면 그 스레드에 할당되어 처리됩니다. 

즉, 1 요청 당 1 스레드가 할당됩니다.

각 스레드에서는 Blocking방식으로 처리되어 응답이 올때까지 그 스레드는 다른 요청에 할당될 수 없습니다.

 

Spring WebClient

Spring WebClient는 Single Thread와 Non-Blocking방식을 사용합니다. 

 

Mono : 0 ~ 1 개의 결과를 처리하기위한 Reactor 객체이다.

Flux : 0 ~ N 개의 결과를 처리하기 위한 Reactor 객체이다

 

<반환타입>

Spring WebFlux를 이용하고 있다면 문제가 없지만 Spring MVC기반이라면 반환값을 객체로 변환해야하는 과정이 생긴다.

이럴때 데이터를 받아오기 위해서 .block()을 사용하는 경우가 있다.

그렇게 된다면 main스레드에서 처리하기 때문에 사용하면 안된다.

사용한다면 테스트때 사용하라고 한다.

 

동기적 사용방법을 설명했지만, Spring MVC/Webflux - Flux, Mono 를 사용하는 환경에서는 절대(Never) block을 사용해서는 안된다. 그냥 단순히 controller 메서드에서 reactive type을 넘기는 식으로 진행해야 한다.

 

대신 완벽한 Reactive 호출은 아니지만 Lazy Subscribe를 통한 Strem 또는 Iterble로 변환시킬 수 있는 Flux.toStream, Flux.toIterable() 함수를 제공하고 있다.

 

출처: 토비의 스프링 3.1 vol.1

출처: https://www.youtube.com/watch?v=26S4VFUWlJM 

참고

 

728x90
Comments