이번에 회사 최초로 시작하는 MSA 개발의 첫 삽을 제가 뜨게 되었습니다!
사실 이 개발을 하면서 제일 큰 걱정은 MSA 책 한 개도 안 봤는데 내가 설계해도 되나......... 였습니다.
설상가상으로 설계기간도 충분하지 못했죠.
하지만 틈틈이 읽은 서적과 블로그들이 큰 도움이 되었고, 부족하지만 제가 설계하고 개발한 기록을 공유합니다.
개발한 내용
기본 구성
오래되고 사용자가 많은 플랫폼 B와 비교적 최근에 개발되었지만 사용자가 적은 플랫폼 P가 존재합니다.
서로 다른 환경에서 운영되고 있던 플랫폼의 각 DB와 회원 등록/수정 로직이 통합 중에도 유지되어야 합니다.
구현된 언어와 프레임워크도 달랐고, 통합 대상인 회원의 식별자와 업무 내용도 미묘하게 달랐습니다.
이해를 돕기 위해 업무 내용의 일부를 먼저 설명하며, 해결하기 위한 설계로 2가지 플랜을 구상했습니다.
- 회원은 거래처(매장)와 같은 의미를 가집니다.
- 거래처는(B: shop, P: cust) 복수 개의 유통사를(B:vendor, P: biz) 가질 수 있습니다.
PLAN A
장점
- 통합회원에는 회원 상세 정보가 없기에 각 플랫폼에서 회원 정보가 변경되어도 알 필요가 없습니다.
- 인증과 직결되는 일부 항목은 필요하지만 개수를 최소화합니다. (ex. 비활성화 여부)
- 로그인 ID(userId)와 password가 통합되고, 인증에 필수적인 필드를 한 곳에서 관리할 수 있습니다.
- 기존 플랫폼의 DB 변경이 최소화됩니다.
단점
- 통합회원에서 회원 상세 정보가 알고 싶다면 각 플랫폼으로 회원 PK를 통해 요청해야 합니다.
PLAN B
장점
- 통합회원에는 회원 상세정보가 없기에 각 플랫폼에서 회원 정보가 변경되어도 알 필요가 없습니다.
- 인증과 직결되는 일부 항목은 필요하지만 개수를 최소화합니다. (ex. 비활성화 여부)
- 로그인 ID(userId)와 password가 통합되고, 인증에 필수적인 필드를 한 곳에서 관리할 수 있습니다.
- 각 플랫폼의 회원 상세정보를 원하는 대로 가져올 수 있습니다.
단점
- 회원 상세정보를 가져오는 네트워크 비용이 비교적 큽니다.
- 기존 플랫폼 DB에 userNo 가 추가됩니다.
상위 도메인은 하위 도메인의 키만을 가지도록 함으로써
리소스 관리의 이슈를 최소화할 수 있도록 설계했습니다.
하지만..
PLAN C
결론적으로 PLAN C의 설계로 개발을 진행하게 되었습니다.
이미 MSA를 경험해본 분이라면 PLAN C의 그림이나 이 글의 제목에서 의아함을 느끼셨을 것 같습니다.
리소스 관리는 도메인 별로 분리된 하나의 서비스에서 하면 되는데, 왜 동기화를 고민하지?
아쉽게도 특수한 업무 요건과 글로 작성하기 힘든 내부의 이슈로 인해 과도기적인 설계를 했어야 되기 때문입니다.
- 인증 진행 간 회원 상세 정보를 보여줘야 하며, 통합인증의 테이블을 사용해야 한다. (스냅샷)
- 각 플랫폼의 회원 등록/수정을 통합 회원에서도 알아야 한다. (동기화)
하지만 요건 만족을 우선한 설계를 했다고 하기에는 부족한 통찰로 합리적인 설득을 하지 못하고 안일하게 넘어간 점이 몹시 아쉽습니다.
마이크로 서비스도 리소스 동기화가 필요할까?
본론을 말하기 위한 배경 설명이 너무 길어졌네요. 다시 처음으로 돌아가겠습니다.
제일 좋은 것은 동기화가 필요하지 않은 설계를 하는 것입니다.
하지만 리얼 월드에서는 앞에서처럼 필요한 경우가 생기곤 하기에, 동기화 방법에 대한 생각을 기록해봅니다.
- 신뢰할 수 있는 리소스는 플랫폼에 있습니다.
- 동기화는 여러 가지 이유로 실패할 수 있습니다.
최악의 경우에는 수동 작업을 해야 될 수도 있는데, 이때를 위한 신뢰할 수 있는 대상을 고려해야 합니다.
신뢰할 수 있는 대상을 정하는 방법은 리소스의 관리 책임 주체는 누구인가? 를 생각하면 될 것 같습니다. - 각 플랫폼에는 상대적으로 많은 회원정보 수정 로직이 있고 수정이 시작되는 지점입니다.
따라서 리소스의 관리 책임이 각 플랫폼에 있다고 간주할 수 있음으로 신뢰할 수 있는 대상은 각 플랫폼이 되어야 하며, 반대로 통합인증의 리소스는 스냅샷으로 간주합니다.
- 동기화는 여러 가지 이유로 실패할 수 있습니다.
- 회원정보 수정은 누가 해야 될까?
- PLAN C에서는 같은 리소스의 관리 대상이 2곳입니다.
따라서 양쪽의 변경이 동시에 하기 위해 수동으로 트랜잭션을 구현해야 합니다.
여기에서 JPA의 양방향 매핑의 연관 관계의 주인에서 인사이트를 얻었습니다.
한쪽을 주인으로 설정하는 것이죠. - 1번을 통해 신뢰할 수 있는 리소스가 플랫폼에 있다는 것을 알 수 있습니다.
따라서 플랫폼이 주인으로서 트랜잭션의 주체로 설계하며 통합인증에서는 키 값과 최소한의 상태만 가지도록 합니다. - 하지만 그럼에도 불구하고 업무 요건에 따라 통합회원에서 정보를 수정해야 되는 경우도 있습니다.
아쉽게도 처음의 아이디어에는 위배되지만 요건 만족을 위해 어쩔 수 없이 예외 로직을 개발했습니다.
이때 트랜잭션의 주체는 반대가 되어야 합니다.
- PLAN C에서는 같은 리소스의 관리 대상이 2곳입니다.
- 동기화 간 지연과 유실을 대비해야 합니다.
- 보편적으로 좋은 해결책은 큐의 도입입니다.
- 큐가 대상으로 push - 재시도는 용이하지만 큐를 를 지속적으로 관리해야 한다.
- 대상이 큐를 polling - 실패 시 이미 소비된 큐가 유실될 위험이 존재한다.
- 보통 큐가 대상으로 push 하는 방식으로 사용됩니다.
- AWS SQS를 통해 권한 제어를 도입하면 보안 향상도 기대할 수 있습니다.
- 보편적으로 좋은 해결책은 큐의 도입입니다.
- 어떤 도메인은 자주 바뀌지 않기에 실시간 동기화에 관대할 수도 있습니다.
- 이 경우 실시간 동기화보다는 배치를 활용하는 방법이 있습니다.
- 실시간 동기화를 하는 경우에도 배치를 사용하여 안정성을 높일 수 있습니다.
- 또는 스냅샷을 캐시로 저장하는 방법도 있습니다. (ex. redis)
- 충분한 환경에서 성숙 단계의 마이크로 서비스를 지향한다면 SAGA 패턴을 고려합니다.
- Choreography와 Orchestration은 구성은 어렵지만 MSA 트랜잭션 관리에 가장 좋은 구조입니다.
마치며
지금 회사의 구성을 MSA로 전환한다면 어떻게 해야 될까?
막연하게 생각했을 때 Step 1처럼 복수의 프로젝트가 하나의 DB를 공유하는 것에서 시작할 것이라고 생각했습니다.
하지만 현실은 많이 달랐고 공부했던 개념들을 모아 독자적인 흐름을 설계했습니다.
그 과정에서 발생한 개발의 어려움은 반대로 좋은 설계의 필요성에 대한 공감대를 형성하기도 했습니다.
제 최종 목표는 플랫폼에서 독립적인 마이크로 서비스와 각 플랫폼에 특화된 Backend for Front-end로 설계하는 것입니다.
아마 이 과정에서도 트레이드 오프를 반복하겠지만 지금의 경험이 도움이 되고, 나아가 이 모든 경험들이 더 좋은 설계의 기반이 되기를 기대하며 글을 마칩니다.
'Study' 카테고리의 다른 글
'AWS와 토스페이먼츠를 통해 E-Commerce 스타트업 혁신하기' 웨비나 후기 (0) | 2022.04.29 |
---|---|
대량 데이터 조회와 유지보수는 어떻게 해야될까? (0) | 2022.04.02 |
'수십억건에서 QUERYDSL 사용하기' 를 보고.. (2) | 2021.12.19 |
String 을 잘 써보자 (0) | 2021.10.16 |
@Component vs @Configuration (0) | 2021.09.25 |