본문 바로가기
CICD/AWS

[Spring/MSA]Msa구조 데이터 롤백 어떻게 해야할까 ??(1)

by windy7271 2024. 8. 2.
728x90
반응형

하.. 아까 쓰던게 사라졌다. 오히려 좋다 복습을 하게 되니

 

자 질문은 

Msa구조에서 순차적으로 api를 요청할 때 1차 api 에서는 정상적으로 처리되어 db 커밋이 완료되었고 2차 api 요청에서 에러가 났을 때 1차 api에서 커밋 된 것을 어떻게 롤백할 것인가 이다.

 

이거에 대한 일단 정답은 SAGA 패턴이라는 것이다.

 

SAGA 패턴을 알아보기 전에

모노로그 식 개발에서는 어떻게 했을까를 생각해보면 서비스 단 혹은 Method 에 @Transactional 을 달아주었다.

 

우리는 @Transactional 하면 그냥 아 중간에 무슨일이 터지면 다시 되돌려 주는거 아니야 ?

 

라고 생각이 든다.

 

맞는 말이다. 근데 중간에 누가? 어디서 해주는지 생각해 보았나 ? 그냥 강의 에서 해준다고 하니 해주는걸로 알고 있었나 ??

 

그래서 이 부분의 대한 의문점을 항상 가지던중 얼마전 RealMySQL 책을 읽다가 알아냈다. 정리를 해보려고 한다.

 

일단 DB에는 언두 영역 이라는게 존재한다. 이 영역은 insert, update ,delete 같은 문장으로 데이터를 변경했을 때 변경되기 전의 데이터 를 보관하는 곳이다.

 

사용자가 커밋하면 현재 상태가 그대로 유지되고, 롤백하면 언두 영역의 백업 된 데이터를 다시 데이터 파일로 저장한다. 

그 저장되는 장소를

 언두 테이블스페이스(저장되는 공간) 

아주 딮 한거 같지만 중요한거 같다.

 

언두로그의 역할은

1. 트랜잭션 롤백 대비용이면서

2. 트랜잭션의 격리 수준을 유지하면서 높은 동시성을 제공한다.

 

즉 만약 A->B->C 로 트랜잭션이 진행될때 중간에 뻑이나면 되돌려준다는것이 언두테이블스페이스에 다시 가져온다고 생각하면 된다.

 

더 자세한 내용은 아래에 설명해두었다.

https://windy7271.tistory.com/entry/mysqlDB-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EC%96%B8%EB%91%90%EB%A1%9C%EA%B7%B8-%EB%A6%AC%EB%91%90%EB%A1%9C%EA%B7%B8-%EB%B2%84%ED%8D%BC

 

그럼 이제 MSA 에 구조에서를 알아보겠다.

 

MSA 의 구조에서의 SAGA 패턴은  데이터의 일관성을 보장하기 위해 등장한 설계패턴이다 . 

 

연속된 개별 서비스의 로컬 트랜잭션이 이어져, 전체 비즈니스 트랜잭션을 구성한다. 첫번째 트랜잭션이 완료되면 두번째 트랜잭션이 트리거 되고, 두번째 트랜잭션이 완료되면 세번째 트랜잭션이 트리거된다.

 

크게 크레오그래피기반, 오케스트레이션 기반으로 이루어진다.

 

오케스트레이션 기반은 모든 트랜잭션을 오케스트레이터(중간 별도의 중계자)가 관리해 트랜잭션의 흐름이 명확하다.

오케스트레이션

  • 마이크로 서비스들의 로컬 트랜잭션이 오케스트레이터에 의해 호출, 상태값 설정
  • 참여자들의 트랜잭션이 모두 처리되면 서비스의 상태 변경
  • 특정 서비스에서 오류가 발생되면 보상 트랜잭션 호출

 

오늘 자세히 해보려는 코레오그래피 기반 사가는 각 서비스가 트랜잭션이 완료되면 그것이 하나의 이벤트이다. 그 이벤트가 다음 이벤트를 실행시키는 방식이다.

 

구성이 편하지만, 각 서비스 마다 종속성이 발생해 결합도가 높다.

  • 트랜잭션이 실패한다면 보상 이벤트를 발행하여 롤백
  • 메시지를 발행하는 동작도 트랜잭션에 포함되어야 함

 

한번 결제 관련 시스템을 통해 구현을 해보려고 한다.

 

과거 나는 order에 관해 msa 구조를 구현을 해놨다. 이것을 좀 수정을 해서 만들어보려고한다.

카프카를 사용해서 이벤트를 구현해서 한 번 해보도록 하겠다.

 

프로세스를 진행하다 실패가 난다면 보상 트랜잭션 이벤트를 발생해야한다.

 

 

성공 시나리오  

 

(1) 사용자 요청을 받은 Order 서비스에서 주문 번호를 생성해서 DB에 적재
(2) Kafka에 주문번호 생성 이벤트 발행
(3) Stock에서 주문번호 생성 이벤트를 구독해서 해당 재고 빼기
(4) Kafka에 재고 빼기 이벤트 발행
(5) Payment에서 재고 빼기 이벤트를 구독해서 결제 프로세스 진행

 

실패 시나리오

(1) Payment 서비스에서 트랜잭션 실패
(2) Payment에서 재고 롤백 이벤트 발행
(3) Stock에서 재고 롤백 이벤트를 구독해서 해당 재고 플러스
(4) Stock에서 주문 롤백 이벤트 발행
(5) Order에서 주문 롤백 이벤트를 구독해서 해당 주문 삭제

 

 

실습 레스고

 

기본틀

 

 

ordering 은 모놀로그식일때 하나로 된것이다. 

사용할 서비스 item, member, ordering 이 세 군대에 카프카 추가. build.gradle

 

ordering 안에 docker - compose . yml 을 추가한다.

 

 

version: '3'
services:
  zookeeper:
    image: wurstmeister/zookeeper
    platform: linux/amd64
    ports:
      - "2181:2181"
    container_name: zookeeper
    restart: always
  kafka:
    image: wurstmeister/kafka
    platform: linux/amd64
    ports:
      - "9092:9092"
    environment:
#      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://10.10.15.112:9092
      KAFKA_ADVERTISED_HOST_NAME: 127.0.0.1
#      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_CREATE_TOPICS: "order-create:1:1, order-rollback:1:1, stock-decrease:1:1, stock-rollback:1:1"
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - zookeeper
    container_name: kafka
    restart: always
  kafka-manager:
    container_name: kafka-manager
    image: hlebalbau/kafka-manager:2.0.0.2
    platform: linux/amd64
    restart: on-failure
    depends_on:
      - kafka
      - zookeeper
    environment:
      ZK_HOSTS: zookeeper:2181
      APPLICATION_SECRET: "random-secret"
      KM_ARGS: -Djava.net.preferIPv4Stack=true
    ports:
      - "9000:9000"

 

간단하게 설명하자면 주키퍼와 카프카를 따로 컨테이너로 띄우고 두 개가 상호작용한다고 보면된다.

카프카를 만들면서 설정으로 topics 들을 만들었다.

 Kafka 브로커가 시작될 때 자동으로 생성할 토픽을 지정하는 역할을 한다. 이 변수는 주로 초기 설정이나 테스트 환경에서 유용하게 사용된다. KAFKA_CREATE_TOPICS는 Kafka 컨테이너가 실행될 때 자동으로 지정된 토픽들을 생성해 주므로, 수동으로 토픽을 생성할 필요 없이 Kafka 브로커를 준비할 수 있다.

 

 

 

 

docker compose up -d 로 설치 죽여버린다

설치중

 

설치완료

 

그러면 일단 뜬거를 확인하실 수 있다.

 

카프카 까지 설치를 완료 했으니 다음에는 구현을 해보려고한다. 

 

곧 작성해서 돌아오겠다.

 

 

 

 

 

 

- 참고문헌

https://hudi.blog/saga-pattern/

https://velog.io/@suhongkim98/MSA%EC%99%80-DDD-Saga-Pattern-6

https://learn.microsoft.com/ko-kr/azure/architecture/reference-architectures/saga/saga
https://devk0ng.github.io/2021/07/27/saga_pattern/#2-Phase-Commit

 

 

 

 

반응형

댓글