MSA ?

신명철·2022년 3월 28일
0

etc

목록 보기
2/5

MSA ?

MSA(MicroService Architecture), 하나의 큰 어플리케이션을 여러개의 작은 어플리케이션으로 쪼개서 변경과 조합이 가능하도록 만든 아키텍처

MSA가 등장하게 된 이유는 Monolithic Architecture에서 출발한다. 이는 MSA와는 반대되는 개념으로, 모든 비즈니스 로직이 하나의 프로젝트에 통합되어 있는 형태를 말한다. 그렇기 때문에 MSA의 필요성을 느끼기 위해서는 우선 Monolithic Architecture에 대한 이해가 필요하다.

Monolithic Architecture

SW의 모든 구성요소가 하나의 프로젝트에 통합되어 있기 때문에 어떤 모듈을 개발했을 때 개발이 완료되고 나면 어플리케이션을 하나의 결과물로 패키징해서 배포하는 형태를 띈다.

Monolithic 형태는 유지보수가 간단하기 때문에 소규모 프로젝트에서 합리적인 선택이 될 수 있다. 하지만, 어플리케이션이 커지면 하나의 프로젝트에 많은 개발자가 붙기 시작하면서 뚜렷한 한계를 보인다.

  • 부분 장애가 시스템 전체의 장애로 이어진다.
  • 서비스 변경이 어렵고 변경 시 시스템 전체에 끼치는 영향을 파악하기 어렵다.
  • 시스템이 커질수록 영향도 파악 및 전체 시스템 구조의 파악에 어려움이 커진다.
  • 빌드 시간/ 테스트 시간/ 배포 시간이 오래 걸린다.
  • 하나의 Framework와 언어에 종속된다.

Micro Service Architecture

최근 어플리케이션의 개발 방법은 CI/CD 를 통한, 개발부터 배포까지를 빠르게 반영하는 추세다. Monolithic Architecture는 이에 어울리지 않았고 특정한 물리적인 서버에 서비스를 올리던 on-premise 서버 기반의 Monolithic Architecture에서 클라우드 환경을 이용하여 서버를 구성하는 MicroService Architecture로 많이 전환되고 있다.

MSA의 특징

MSA를 구성하고 있는 서비스들은 자체 프로세스에서 실행되고 느슨한 연결 구조로 연결구조로 만들어져서 REST와 같은 경량 매커니즘과 통신을 하게 된다.

MSA는 API를 통해서만 상호작용할 수 있다. 즉, MicroService는 end-point를 API 형태로 외부에 노출하고, 실질적인 세부 사항은 모두 추상화한다. 내부의 구현 로직, 아키텍처, 언어, DB와 같은 기술적인 사항들은 서비스 API에 의해서 철저하게 가려진다.

MicroService는 하나의 비즈니스 범위에 맞추어 만들어진다. 즉, 개발자들은 어플리케이션 출시라는 하나의 목표를 위해 일하지만, 자기가 개발하는 서비스에 대해서만 책임을 지게 된다.

REST 같은 중립적 프로토콜을 통해 통신하기 때문에 각각의 MicroService는 서로의 언어와 프레임워크와 무관하게 개발하게 된다. 서비스의 특징에 맞는 다양한 언어와 프레임워크를 사용할 수 있다.

MSA의 장점

  • MSA는 ESB(Enterprise Service Bus) 같은 무거운 제품에 의존하지 않는다. REST 등 가벼운 통신 아키텍처나 Kafka 등을 이용한 Message Stream을 주로 사용한다. 이러한 특징은 각각의 개별 서비스 개발을 빠르게 하고 유지보수도 쉽게 할 수 있도록 한다.
  • 서비스 단위로 적절한 기술 스택을 사용할 수 있다.
  • 서비스 별 독립적 배포가 가능하다.
  • 서비스 부하에 따라 개별적으로 scale-out이 가능하다.

MSA의 단점

MSA와 모듈형 아키텍처 스타일은 클라우드 기반의 환경에 적합하고, 도커나 쿠버네티스와 같은 컨테이너 기반의 플랫폼과 조합이 잘 어울려 많이 발전하고 있다. 하지만 MSA 를 적용하려고 할 때 많은 난관에 부딪히게 된다.

  • 개발 복잡도와 숙련도
    • Monolithic 시스템에 비해서 복잡하기 때문에 개발자는 내부 시스템의 통신을 어떻게 가져야할지 정해야 한다. 요청에 응답하지 않는 경우에 대비한 코드를 작성해야 하고, 만약 호출 대기 시간이 일정 수준을 넘기면 복잡한 상황이 발생할 수 있다. 그리고 동기적인 처리방식인 REST 통신으로 인한 제약이 발생할 수 있다.
  • 트랜잭션 관리
    • MSA는 DB per Service 즉, 분산된 서비스마다 독립적인 DB를 갖는다. 따라서 분리된 DB들 끼리의 트랜잭션을 관리하는데에 어려움이 따를 수 있다.
  • 통합 테스트/ 배포 복잡도
    • MSA 를 테스트할 때는 실제 운영환경과 개발환경을 동일하게 가져간다는 것이 쉽지 않다.

EDM (Event-Driven MicroService)

MSA 문제점들은 자동화 도구나 비즈니스 상황에 맞춰 수정된 아키텍처를 적용해 해결할 수 있다. EDM은 MSA가 적용된 시스템에서 이벤트 발생시 해당 이벤트 로그를 보관하고 이를 기반으로 동작한다. 비동기 통신을 통해 시스템 내 통합(Integeration)을 수행하는 Architecture다.

이벤트 ?
상태의 변경 즉, 데이터의 변경이나 생성, 삭제를 통해 발생하는 서비스의 의미있는 변화를 뜻한다.

Event Driven?

Event Driven 아키텍처는 특정 서비스에서 다른 서비스가 관심을 가질 수 있는 일부 작업을 수행할 때 해당 서비스는 이벤트(작업 기록)를 생성하게 된다. 다른 서비스는 이벤트들을 전달받고 필요시 자체 작업을 수행한다. REST 와는 다르게 이벤트를 통해 느슨한 구조로 요청을 생성하는 서비스는, 요청을 소비하는 서비스의 세부 정보를 알 필요가 없다.

Event Driven은 Programming, Architecture 과 연결되어 다양한 정의로 표현된다. Event Driven 은 분산 처리 시스템과 연결되어 느슨한 결합을 지원하고 유연성, 탄력성, 확장성 있는 시스템을 구현할 수 있도록 해준다.

  • 마우스 클릭, 키보드 타이핑 등 컴퓨터 회로를 구동시키기 위해서 발생하는 일
  • 특정 행동이 순서에 따라 발생하는 것이 아닌 어떤 일에 대한 반응으로 동작하는 디자인 패턴
  • IOT 기기 등의 센서로부터 유입되는 데이터 스트리밍 기반의 동작
  • 시스템 내 외부에 발생한 주목할 만한 상태의 변화에 기반한 동작
  • 기타 등등

이벤트 로그를 보관하는 이유 ?
현재의 데이터는 상태 변경의 누적이라는 생각에서 시작한다. 이 때, 상태 변경은 데이터를 뜻하고 이를 누적하는 행위는 이벤트 로그를 보관하는 것이다. EDM 에서 생성된 이벤트는 반드시 보관해야 한다. 보관된 이벤트는 데이터의 현재 상태를 구성하는 근간이 되기 때문이다. 또한 보관된 이벤트를 바탕으로 장애 발생 혹은 특정 요구사항에 따라 지정된 시점으로 복원을 수행할 수 있다. 이벤트 로그를 보관하는 장소를 이벤트 버스(스토어)라고 칭한다.

Event Bus(Store)

이벤트는 다양한 방식으로 게시될 수 있다. 예를 들어 적절한 소비자에게 전달하도록 보장하는 대기열에 이벤트를 게시하거나, 모든 이해 당사자에게 액세스를 허용하는 pub-sub 메시지 모델에 따라 게시할 수 있다. 위 두 경우 모두 생산자는 이벤트를 생성하고, 소비자는 이벤트를 수신해 그에 따라 반응하게 된다.

대기열 처리 방식으로 대표적으로 ActiveMQ, RabbitMQ 가 있고, pub-sub 메시지 모델로는 대표적으로 Apache Kafka를 많이 사용한다.

비동기 통신과 동기 통신

MSA에서는 크게 2가지 방식으로 통신을 한다. 이들 모두 장점과 단점이 있기 때문에 상황에 따라 적합한 방식을 선택해야 한다.

요청/응답 모델

요청/응답 모델은 동기 통신에 단일 통신 방법이다. 요청자는 응답자의 주소를 알고 있어야하는 Point to Point 방식으로 통신을 하게 된다. 이 방식은 서비스가 증가할수록 주소가 늘어나고 서비스가 복잡하게 연결된다. 동기 통신이기 때문에 응답자의 서비스가 항상 떠있어야 하고 응답 서비스에서 오랜 시간을 소비하면 그만큼 응답이 느려지기 때문에 Blocking 모델이다. 또 요청 체인이 길어지면 장애 전파(Fault Spread)의 위험성이 있다.

Pub-Sub 모델

발행-구독 모델은 비동기 통신에 Broadcasting이 가능하다. 이벤트 게시자는 구독자의 주소를 알 필요가 없고 수신 여부를 확인할 필요도 없다 즉, Non-Blocking 모델이다. 수신자의 서비스가 항상 떠있을 필요가 없고, 이로 인해 장애(Fault Isolation)가 격리된다(수신자의 응답에 영향을 받지 않기 때문).

Event-Driven 어플리케이션에서는 Pub-Sub 모델을 채택한다.

Event Driven MicroService 를 MSA 에 적용하는 이유

1. Database Per Service

Database Per Service 는 MSA의 느슨한 결합, 관심사의 집중, 폴리글랏 프로그래밍, 독립적인 배포 주기 등을 달성하기 위한 핵심 키워드다.

MSA를 적용할 때 Database Per Service는 가장 어려운 부분 중 하나다. 그 이유는 DB를 분리할 때 고려해야 할 요소들이 있기 때문이다. 기존의 Shared DB 구성, 그 중 관계형 DB를 사용하는 경우에는 ACID 원칙에 따른 트랜잭션 처리, 모든 테이블에 접근해 Join을 통한 통합 뷰 제공, 관계를 활용한 효율적인 데이터 저장 및 조회 등 DBMS 레벨에서 여러 유용한 기능을 제공했다.

하지만, 중앙화된 Shared DB를 사용하게 MSA의 이점을 살리기 어렵다. 시스템의 응집력을 저해하고 종속성을 높이고, 단일 트랜잭션 처리에 따라 테이블 락 등 장애 발생 가능성, 장애 발생시 장애가 시스템 전체로 퍼지고, 스케일링이 어렵고, 서비스마다 최적화된 DB를 선택할 수 없기 때문이다.

MSA에서 DB Per Service를 적용하면, Shared DB 구성의 DBMS 레벨에서 제공하던 기능들을 어플리케이션 레벨에서 해결해야만 한다. EDM은 DBMS 어플리케이션에서 최종 일관성을 지원해 트랜잭션 처리를 수행하는 것에 적합하고, 서비스 목적에 최적화된 DB를 선택하는 것에 도움을 준다.

폴리글랏

모바일,SNS,IOT 등의 발전으로 인해 데이터는 스트림 형태의 비정형 데이터가 많아지고 있다. 빠른 읽기/쓰기 성능을 지원하기 위해 분산형 구조를 이용해 데이터를 여러 대의 서버에 저장하게 된다. 상호 복제를 통해 서버 장애로 인한 데이터 유실이나 서비스 중지가 없는 형태의 구조 등 기존 RDB에 최적화 되지 않은 기능을 요구한다. 확장성, 단순한 구조, 느슨한 정합성, 낮은 비용, 빠른 검색등의 NoSQL DB가 적합하다. 이런 경우 MSA의 DB Per Service를 적용해 서비스의 목적에 맞는 최적의 DB를 선택할 수 있다.

2. 트랜잭션 처리

기존 Monolithic 시스템에서는 문제 발생 시 rollback 이나 retry 를 수행한다. 그렇기 때문에 문제 발생 이전 시점으로 돌아가 데이터를 수정할 수 있다. 하지만 MSA 시스템에서는 서로 다른 서비스에 걸쳐진 기능을 수행하던 중 일관된 commit이나 rollback을 수행할 수 없다. 이때 EDM 을 적용해 rollback 또는 retry를 해 문제는 처리할 수 있다.

rollback이 필요한 경우 Failed 이벤트를 발생시키고 이를 이전 스텝을 수행한 서비스에서 구독하여 보관되어 있던 이벤트 로그 기반으로 rollback을 수행한다.

3. 반정규화 데이터 동기 처리

MSA 시스템에서는 비즈니스 로직과 이를 수행하는데 필요한 데이터가 서로 다른 서비스에 나뉘어져 있을 수 있다. 처음에는 여러 서비스간 REST 통신을 통해 데이터를 참조할 수 있지만, 서비스가 커져가면 복잡성/성능 등의 이유로 서비스 간 데이터 반정규화가 발생할 수 있다. 이 때 EDM 을 적용해 서비스 간 데이터 동기 처리를 수행할 수 있다.

4. 최종 일관성

기존 DBMS 를 활용한 ACID 트랜잭션에 따른 무결성 보장은 MSA에서 서비스와 DB가 나누어 가짐으로써 더는 달성할 수 없다. 대신 EDM을 사용해 데이터의 최종적인 일관성 유지로 변경된다.

-> all commit or rollbakc -> eventually consistency


참고

profile
내 머릿속 지우개

0개의 댓글