MSA 프로젝트 패턴 1

배지원·2024년 5월 8일

MSA

목록 보기
2/12

1. 분해 패턴

MSA 소프트웨어 아키텍처를 설계합에 있어서, 모놀리식 비즈니스 구조를 어떤 판단 기준에 따라 서비스를 분리할 것인지에 대한 패턴 즉, "분해"를 해결하기 위한 패턴

(1) 도메인 주도 설계(Domain-Driven Design, DDD)

도메인 주도 설계는 비즈니스 도메인을 중심으로 마이크로서비스를 식별하고 정의하는 방법론입니다. 각 도메인은 서로 관련된 비즈니스 기능을 포함하며, 이러한 도메인을 기반으로 마이크로서비스를 분해합니다.
Ex) 계좌 도메인, 내부 머니 도메인, 뱅킹(외부 은행과 통신만 담당)...

장점

  • 서비스 간 독립성, 격리성이 증가 / 결합도 감소
  • 서비스 간 종속성 최소화, 서비스 간 영향도 감소
  • 장애 영향도 최소화
  • MSA 철학에 부합하는 패턴


    단점
  • 서비스 간 불필요한 통신 가능성, 성능 이슈
  • 지나치게 많은 시버스로 분리될 가능성
  • 대규모 시스템에서는 비효울성 크게 증가 가능성

(2) 서비스 정렬 패턴

서비스 정렬은 특정 비즈니스 프로세스 또는 사용 사례에 따라 마이크로서비스를 정렬하는 방식입니다. 여러 마이크로서비스가 협력하여 특정 비즈니스 프로세스를 수행하도록 설계됩니다.
Ex) 송금 서비스, 주문 서비스,...

장점

  • 비즈니스가 복잡하고, 대규모 조직의 경우
  • 비즈니스 특성으로 인해 내부 서비스간 통신이 매우 빈번할 경우


    단점
  • 서비스가 응집도, 결합도, 종속성 증가
  • 서비스, 즉 도메인 별 팀의 구조가 희석될 가능성

2. 통신 패턴

MSA 설계를 통해 도출된 서비스 간 어떤 방식으로 통신을 할 지 결정하는 패턴 즉, "통신"을 해결하기 위한 패턴

(1) Sync Pattern (동기 패턴)

어떤 서비스가 다른 서비스로 특정 Request 이후, 그 Response를 받을 때까지 멈춰있어도 되는 경우 즉, 요청을 하면 바로 응답이 오는 방식으로 직관적이기에 가장 많이 사용되고 있습니다. 하지만, 호출 받은 마이크로서비스에 장애가 발생하게 되면 요청을 보낸 서비스는 응답이 올때까지 계속 기다리며 호출을 하게 됩니다.

여러 서비스간 연계를 통한 방식인 마이크로서비스 구조에서는 이러한 상황에서 장애가 연쇄적으로 발생할 수 있습니다.

Ex) HTTP(Restful), gRPC


(2) Async Pattern (비동기 패턴)

어떤 서비스가 다른 서비스를 특정 Request 이후, 그 Response를 당장은 받지 않아도 되어 응답을 기다리지 않고 다음 일을 처리합니다. 하지만, 보낸 결과가 어떻게 됐는지 응답을 받지 않으므로 동기식처럼 완결성을 보장할 수는 없습니다.

따라서 이를 해결하고자 Kafka를 활용하게 되는데
메시지를 보내는 생산자와 메시지를 받아 처리하는 소비자가 서로 직접 접속하지 않고 메시지 브로커에 연결되고, 메시지 브로커에 메시지를 전달하고 자신의 일을 처리하면 메시지 브로커가 전송을 보장하게 됩니다.
이때, 여러 서비스에서 전달한 메시지를 처리하는 브로커 자체에 부하가 생길수 있으므로 해당 경우에는 메시지 브로커는 메시지 처리 규모에 따라 확장이 가능합니다.

해당 방식은 메시지 브로커에 의해 중계되기 때문에 서로 통신하는 서비스들이 물리적으로 동일한 시스템에 위치할 필요도 없고 서로 프로세스를 공유할 필요도 없게 됩니다. 따라서 서비스 요구에 따라 늘어나거나 줄어들 수 있는 탄력성이 높은 클라우드 플랫폼 환경에서 서비스가 다운 됐을 때 또는 시스템을 더 확장해야할 때 사용할 수 있는 방법입니다.

Ex) Kafka 등을 이용한 Message Queueing, Callback, Polling,...


3. 트랜잭션 패턴

MSA 설계를 통해 도출된 서비스를 사용하여 트랜잭션을 해결해 주기 위한 패턴으로 MSA에서 트랜잭션은 분산 시스템 전체에서 데이터 일관성과 무결성을 보장하는데 사용됩니다.
예 ) 한 은행 계좌에서 다른 은행 계좌로 돈이 이체되는 경우 거래가 올바르게 완료되고 돈이 이체되는지 확인되어야 함. 트랜잭션 중에 네트워크 오류 또는 데이터베이스 오류와 같은 오류가 발생하면 트랜잭션을 원래 상태로 롤백하여 데이터가 일관되고 정확하게 유지되도록 해야함. 이는 오류를 견디고 데이터 일관성과 무결성을 보장할 수 있는 안정적으로 강력한 분산 시스템을 구축해야 합니다.


(1) 2-Phase-Commit(2PC)

"트랜젝션의 완료"를 2(N)단계에 거쳐서 결정

Prepare Phase (준비 단계)
트랜잭션 매니저 (TM)는 모든 리소스 매니저 (RM)에게 트랜잭션 커밋 준비를 알립니다. RM들은 이 요청을 받고 필요한 모든 작업을 준비하며 준비가 완료되면 응답합니다.


동작방식
1. 금액 이체를 요청
2. Cordinator는 해당 서비스를 구현하기 위해 A,B계좌에 Prepare 준비단계인지 확인함
3. 각 계좌 서비스는 상태를 확인하여 준비가 되었다면 준비 완료 응답을 하고, 아직 준비가 되어 있지 않다면 실패 응답을 반환합니다.

Commit/Rollback Phase (커밋/롤백 단계)
모든 RM이 준비되면 TM은 트랜잭션을 커밋합니다. 만약 어떤 RM이 준비되지 않았다면, TM은 트랜잭션을 롤백합니다. 하지만 이렇게 되면 송금서비스에서는 준비완료를 반환받고 계좌 확인 서비스에서 오류가 발생하여 아무런 응답을 받지 못한 경우 이미 송긍 서비스에 대해서는 준비 완료를 반환 받았기 때문에 오류가 발생하게 됩니다.


동작방식
1. Cordinator는 모든 계좌 서비스로부터 응답을 받습니다.
2. 만약 모든 서비스가 준비 완료 응답을 반환하게 되면 Cordinator는 각 계좌 서비스에 커밋을 요청하게 됩니다. 커밋의 호출에 따라 A계좌에서는 출금이 이루어지고, B계좌에서는 입급이 됩니다.
3. 그러나 하나 이상의 서비스에서 준비실패 응답을 받게 된다면 Cordinator는 RollBack을 요청합니다.


(2) Compensation Transactions(보상 트랜잭션)

2PC의 단점을 보완하기 위해 나온 트랜잭션으로 특정 요청과 그 요청에 대해 정상적이고 완전히 종료된 "행동"(트랜잭션)을 그 이전 상태로 되돌리기 위한 "행동"(트랜잭션)

2PC와 다르게 이미 준비완료 응답을 받은 서비스가 있어도 다른 서비스에서 에러가 발생하여 응답을 받지 못하게 된다면 현재 진행된 서비스에 대해서 Compensating Transaction을 진행하게 됨, 하지만 이 또한 무조건 가능하다는 보장이 없고 송금 서비스에서 Transaction이 불가능한 경우도 생김


(3) Saga Pattern

2PC와 보상 트랜잭션의 장점을 모아둔 트랜잭션으로 트랜잭션의 선, 후 관계를 사전에 정의하고 필요와 경우에 따라 Cordinator가 보상 트랜잭션을 이용, 관리하여 분산 시스템 환경에서 트랜잭션을 구현하기 위한 패턴

  1. 요청(트랜잭션)이 들어오게 됩니다
  2. 송금 서비스에서 오류가 없다면 Done을 통해 준비완료 응답을 함과 동시에 첫 서비스 응답때 Saga를 시작해줍니다.
  3. 해당 요청에 필요한 다른 서비스들도 똑같이 진행하여 Cordinator에 준비 완료 응답을 보내게 됩니다.
  4. 만약 이때 계좌 확인 서비스에서 오류가 발생하게 되면 Cordinator에 문제가 있다는 신호를 보내주게 되고 Cordinator에 이미 사전에 해당 트랜잭션을 실행하는데 사용된 서비스를 정의를 해둔 것을 가져와 해당 서비스에 대해 Compensating Transaction(보상 트랜잭션)을 실행하여 복구하게 됩니다.
  5. 하지만 2PC처럼 계좌 확인 서비스에서 에러가 발생하여 Cordinator에 응답을 못하는 경우도 발생하게 되는데 이때는 Saga가 시작하고 나서 타임아웃을 통해 정한 시간안에 성공/실패의 응답이 오지 않는다면 이 또한 Compensating Transaction(보상 트랜잭션)을 실행하여 복구하게 됩니다.


참고 자료
MSA 통신 패턴

Saga 패턴

2PC / Saga 패턴

profile
Web Developer

0개의 댓글