MSA는 어렵다고들 합니다. 왜 그런걸까요
그 이유는 바로 정답이 없기 때문이 아닐까 생각한다. MSA를 하면서 좋다고는 생각하지만, 막상 다른 사람들에게 왜 좋은지에 대해 설명하고, MSA를 쉽사리 전파해 주기란 쉽지 않은 일이다.
사실 MSA의 개념은 오래전부터 존재해왔다. 하지만 과거에는 이러한 아키텍처를 위한 기술, 구현 및 운영을 위한 자원, 그리고 전문성을 가진 인력이 충분하지 않아 발전과 적용이 어려웠다. 하지만 최근 클라우드 기술의 발달과 함께 컨테이너 기술의 발전이 마이크로 서비스 아키텍처 기반의 서비스 구성과 운영을 가능하도록 이끌고 있다.
2011년 5월 베니스에서 개최된 소프트웨어 아키텍처의 워크숍에서 "마이크로서비스"(microservice)라는 용어를 사용하여 참여자들이 공통의 아키텍처 스타일을 본바, 즉 참여자 중 다수가 최근 탐구했던 바를 기술하였다. 2012년 5월, 동일 그룹은 "마이크로서비스"를 가장 적절한 이름으로 결정하였다. 제임스 루이스는 2012년 3월 33rd Degree in Kraków in Microservices - Java, the Unix Way에서 사례 연구로 이 아이디어 가운데 일부를 발표했는데, 이는 프레드 조지가 거의 같은 시기에 했던 내용과 같다. "섬세한 SOA"(fine grained SOA)으로 이러한 접근을 설명한 넷플릭스의 에이드리언 콕크로프트는 웹 규모로 이 스타일을 개척했는데, 다른 사람들 다수(Joe Walnes, Dan North, Evan Bottcher, Graham Tackley)가 이 문서에서 언급한 바와 같다.[15]
또한 코로나라는 전대미문의 바이러스의 창궐과 함께 전세계적으로 발생하고 있는 폭발적인 트래픽을 감당하기에 보다 더 효율적이고 경제적인 아키텍처로 판단되어 선택되는 경우도 많아지고 있다.
대표적인 예로 백신예약 시스템이 있다.
http://www.koit.co.kr/news/articleView.html?idxno=87638
COVID-19라는 홍역을 치루면서 시스템이 최소한 먹통은 되지 않아야 한다는 것을 사람들이 인식하기 시작했다. 시스템이 정상 동작을 하지 않더라고 최소한 사용자에게 에러 화면이라도 보여주어야 UX 관점에서 사람들에게 외면받고 버려지는 시스템이 되지 않을 수 있다.
이런 접속 장애보다..
이런 화면이 낫지 않을까?
더이상 사람들은 100% 완벽한 시스템/서비스를 원하지 않는다. 지금 당장 서비스가 불가하다면 적어도 왜 그런지(DB장애라던지), 언제쯤 서비스를 이용할 수 있는지, 대기는 얼마나 해야 하는지에 대한 명확한 안내가 제공되기를 원하며, 나아가 사용자의 피드백이 시스템에 빠른 기간내에 녹아드는 것을 더 선호하는 시대가 되었다.
마이크로 서비스, 즉 서비스를 잘게 나누어 놓으면 트래픽의 유연한 처리가 가능하다는 것이 가장 큰 장점이다. 서비스 단위가 작기 때문에 만일 서비스가 정상 동작을 하지 않는 상태가 된다면 해당 서비스를 기동 중지(kill, shutdown)하고 새로운 서비스 인스턴스를 기동시키면 된다. 만일 트래픽이 증가하여 서비스 부하가 증가하면 더 많은 수의 서비스 인스턴스를 만들면 된다.
그러면 MSA는 어떻게 구성해야 할까?
MSA를 한다는 것은 특정 프레임워크를 사용하거나 개발 언어에 종속되는 아키텍처는 아니다.
프레임워크나 언어에 종속되지 않고 각각의 서비스들이 상호간 동기/비동기 어떤 형태로든 통신(http, kafka 등) 을 할 수 있으면 된다. 좀 더 MSA스럽기 위해서는 HTTP와 같은 Sync (강결합) 통신방식 보다는 Kafka 와 같은 Queue 를 활용한 비동기 통신(약결합)을 통해 서비스들 간의 통신이 이루어지면 좋다. 통신방식이 강결합에서 약결합으로 될수록 특정 서비스의 업그레이드/교체와 같은 상황에 대한 처리가 쉬워지며 비로소 서비서를 언제든 사용하다가 중지시키고 변경할 수 있게 된다.
이러다 보니 어떤 진영에서는 극단적으로 '재사용성/다형성 이런 것들을 고민할 시간에 차라리 하드코딩을 하더라도 100% 신뢰할 수 있고 동작하는 코드를 빨리 배포해서 시장에 내놓는 것이 낫다'라고 주장하기도 한다. 이것을 가능하게 해주는 것이 MSA이기도 하다. 서비스간의 연결은 모두 인터페이스를 통해 이루어지니 각 서비스가 어떻게 구성되어 있는지 세세히 들여다 볼 필요가 없다. 조금 비효율적이거나 문제가 있는 코드라도 새로운 컨테이너를 추가하거나 개선하여 교체하기만 하면 된다. 이렇게 생각하다보면 코드 작성에 걸리는 시간이 짧아지게 되고 오류도 적어지며, 결국 배포가 빨라지게 된다.
결과적으로 MSA를 적용하게 되면 개발과 배포 속도가 빨라지고, 부하와 장애에 보다 유연하게 대처가 가능하며, 클라우드 서비스 환경에 적합한 아키텍처를 구성할 수 있다.
(다만 운영 복잡성은 매우 증가하게 된다)
지금까지 간단히 MSA가 무엇인지, 왜 해야하는지 살펴봤다.
이제 전문적인 글과 함께 MSA에 대해 깊이 알아보자.
https://www.samsungsds.com/kr/insights/1239180_4627.html
https://devops.com/implementing-message-queue-in-kubernetes/
https://www.samsungsds.com/kr/insights/1239180_4627.html
- 라이브러리를 공유하거나 유사한 기능들은 하나의 서비스로 통합
SAGA 패턴은 애플리케이션 레벨에서 수행하고 2PC·CDC(change data capture)는 시스템 소프트웨어가 담당하느냐의 차이가 있을 뿐 궁극적인 실행 결과는 동일합니다. SAGA 패턴은 표현력이 더 넓어서 보상 트랜잭션 구성 방식에 따라 2PC와 CDC의 효과를 모두 낼 수 있습니다. 다만 모든 보상 트랜잭션을 완벽하게 구성하는 것이 현실적으로 어려울 수 있으며 단계별 에러 케이스를 다 검증해야 하는 부담이 있습니다. 강한 정합성(Strong Consistency)은 2PC만 보장할 수 있습니다. 반드시 반영되어야 하는 케이스인데 SAGA 패턴으로 보상 거래를 기술하기 복잡하다면 CDC가 구성이 단순하고 안정적이므로 더 적합하다고 할 수 있습니다.
MSA 아키텍처 모델링 및 실습 예제 1 - 숙소예약
숙소예약(AirBnB)
본 예제는 MSA/DDD/Event Storming/EDA 를 포괄하는 분석/설계/구현/운영 전단계를 커버하도록 구성한 예제입니다. 이는 클라우드 네이티브 애플리케이션의 개발에 요구되는 체크포인트들을 통과하기 위한 예시 답안을 포함합니다.
Table of contents
서비스 시나리오
AirBnB 커버하기
기능적 요구사항
- 호스트가 임대할 숙소를 등록/수정/삭제한다.
- 고객이 숙소를 선택하여 예약한다.
- 예약과 동시에 결제가 진행된다.
- 예약이 되면 예약 내역(Message)이 전달된다.
- 고객이 예약을 취소할 수 있다.
- 예약 사항이 취소될 경우 취소 내역(Message)이 전달된다.
- 숙소에 후기(review)를 남길 수 있다.
- 전체적인 숙소에 대한 정보 및 예약 상태 등을 한 화면에서 확인 할 수 있다.(viewpage)
비기능적 요구사항
- 트랜잭션
- 결제가 되지 않은 예약 건은 성립되지 않아야 한다. (Sync 호출)
- 장애격리
- 숙소 등록 및 메시지 전송 기능이 수행되지 않더라도 예약은 365일 24시간 받을 수 있어야 한다 Async (event-driven), Eventual Consistency
- 예약 시스템이 과중되면 사용자를 잠시동안 받지 않고 잠시 후에 하도록 유도한다 Circuit breaker, fallback
- 성능
- 모든 방에 대한 정보 및 예약 상태 등을 한번에 확인할 수 있어야 한다 (CQRS)
- 예약의 상태가 바뀔 때마다 메시지로 알림을 줄 수 있어야 한다 (Event driven)
체크포인트
- 분석 설계
- 이벤트스토밍:
- 스티커 색상별 객체의 의미를 제대로 이해하여 헥사고날 아키텍처와의 연계 설계에 적절히 반영하고 있는가?
- 각 도메인 이벤트가 의미있는 수준으로 정의되었는가?
- 어그리게잇: Command와 Event 들을 ACID 트랜잭션 단위의 Aggregate 로 제대로 묶었는가?
- 기능적 요구사항과 비기능적 요구사항을 누락 없이 반영하였는가?
- 서브 도메인, 바운디드 컨텍스트 분리
- 팀별 KPI 와 관심사, 상이한 배포주기 등에 따른 Sub-domain 이나 Bounded Context 를 적절히 분리하였고 그 분리 기준의 합리성이 충분히 설명되는가?
- 적어도 3개 이상 서비스 분리
- 폴리글랏 설계: 각 마이크로 서비스들의 구현 목표와 기능 특성에 따른 각자의 기술 Stack 과 저장소 구조를 다양하게 채택하여 설계하였는가?
- 서비스 시나리오 중 ACID 트랜잭션이 크리티컬한 Use 케이스에 대하여 무리하게 서비스가 과다하게 조밀히 분리되지 않았는가?
- 팀별 KPI 와 관심사, 상이한 배포주기 등에 따른 Sub-domain 이나 Bounded Context 를 적절히 분리하였고 그 분리 기준의 합리성이 충분히 설명되는가?
- 컨텍스트 매핑 / 이벤트 드리븐 아키텍처
- 업무 중요성과 도메인간 서열을 구분할 수 있는가? (Core, Supporting, General Domain)
- Request-Response 방식과 이벤트 드리븐 방식을 구분하여 설계할 수 있는가?
- 장애격리: 서포팅 서비스를 제거 하여도 기존 서비스에 영향이 없도록 설계하였는가?
- 신규 서비스를 추가 하였을때 기존 서비스의 데이터베이스에 영향이 없도록 설계(열려있는 아키택처)할 수 있는가?
- 이벤트와 폴리시를 연결하기 위한 Correlation-key 연결을 제대로 설계하였는가?
- 헥사고날 아키텍처
- 설계 결과에 따른 헥사고날 아키텍처 다이어그램을 제대로 그렸는가?
- 이벤트스토밍:
- 구현
- [DDD] 분석단계에서의 스티커별 색상과 헥사고날 아키텍처에 따라 구현체가 매핑되게 개발되었는가?
- Entity Pattern 과 Repository Pattern 을 적용하여 JPA 를 통하여 데이터 접근 어댑터를 개발하였는가
- [헥사고날 아키텍처] REST Inbound adaptor 이외에 gRPC 등의 Inbound Adaptor 를 추가함에 있어서 도메인 모델의 손상을 주지 않고 새로운 프로토콜에 기존 구현체를 적응시킬 수 있는가?
- 분석단계에서의 유비쿼터스 랭귀지 (업무현장에서 쓰는 용어) 를 사용하여 소스코드가 서술되었는가?
- Request-Response 방식의 서비스 중심 아키텍처 구현
- 마이크로 서비스간 Request-Response 호출에 있어 대상 서비스를 어떠한 방식으로 찾아서 호출 하였는가? (Service Discovery, REST, FeignClient)
- 서킷브레이커를 통하여 장애를 격리시킬 수 있는가?
- 이벤트 드리븐 아키텍처의 구현
- 카프카를 이용하여 PubSub 으로 하나 이상의 서비스가 연동되었는가?
- Correlation-key: 각 이벤트 건 (메시지)가 어떠한 폴리시를 처리할때 어떤 건에 연결된 처리건인지를 구별하기 위한 Correlation-key 연결을 제대로 구현 하였는가?
- Message Consumer 마이크로서비스가 장애상황에서 수신받지 못했던 기존 이벤트들을 다시 수신받아 처리하는가?
- Scaling-out: Message Consumer 마이크로서비스의 Replica 를 추가했을때 중복없이 이벤트를 수신할 수 있는가
- CQRS: Materialized View 를 구현하여, 타 마이크로서비스의 데이터 원본에 접근없이(Composite 서비스나 조인SQL 등 없이) 도 내 서비스의 화면 구성과 잦은 조회가 가능한가?
- 폴리글랏 플로그래밍
- 각 마이크로 서비스들이 하나이상의 각자의 기술 Stack 으로 구성되었는가?
- 각 마이크로 서비스들이 각자의 저장소 구조를 자율적으로 채택하고 각자의 저장소 유형 (RDB, NoSQL, File System 등)을 선택하여 구현하였는가?
- API 게이트웨이
- API GW를 통하여 마이크로 서비스들의 집입점을 통일할 수 있는가?
- 게이트웨이와 인증서버(OAuth), JWT 토큰 인증을 통하여 마이크로서비스들을 보호할 수 있는가?
- [DDD] 분석단계에서의 스티커별 색상과 헥사고날 아키텍처에 따라 구현체가 매핑되게 개발되었는가?
- 운영
- SLA 준수
- 셀프힐링: Liveness Probe 를 통하여 어떠한 서비스의 health 상태가 지속적으로 저하됨에 따라 어떠한 임계치에서 pod 가 재생되는 것을 증명할 수 있는가?
- 서킷브레이커, 레이트리밋 등을 통한 장애격리와 성능효율을 높힐 수 있는가?
- 오토스케일러 (HPA) 를 설정하여 확장적 운영이 가능한가?
- 모니터링, 앨럿팅:
- 무정지 운영 CI/CD (10)
- Readiness Probe 의 설정과 Rolling update을 통하여 신규 버전이 완전히 서비스를 받을 수 있는 상태일때 신규버전의 서비스로 전환됨을 siege 등으로 증명
- Contract Test : 자동화된 경계 테스트를 통하여 구현 오류나 API 계약위반를 미리 차단 가능한가?
- SLA 준수
- 마이크로 서비스를 넘나드는 시나리오에 대한 트랜잭션 처리
- 고객 예약시 결제처리: 결제가 완료되지 않은 예약은 절대 받지 않는다고 결정하여, ACID 트랜잭션 적용. 예약 완료시 사전에 방 상태를 확인하는 것과 결제처리에 대해서는 Request-Response 방식 처리
- 결제 완료시 Host 연결 및 예약처리: reservation 에서 room 마이크로서비스로 예약요청이 전달되는 과정에 있어서 room 마이크로 서비스가 별도의 배포주기를 가지기 때문에 Eventual Consistency 방식으로 트랜잭션 처리함.
- 나머지 모든 inter-microservice 트랜잭션: 예약상태, 후기처리 등 모든 이벤트에 대해 데이터 일관성의 시점이 크리티컬하지 않은 모든 경우가 대부분이라 판단, Eventual Consistency 를 기본으로 채택함.
음식배달 서비스 MSA 아키텍처링 예시
배달의 민족 커버하기 - https://1sung.tistory.com/106
기능적 요구사항
1. 고객이 메뉴를 선택하여 주문한다
2. 고객이 결제한다
3. 주문이 되면 주문 내역이 입점상점주인에게 전달된다
4. 상점주인이 확인하여 요리해서 배달 출발한다
5. 고객이 주문을 취소할 수 있다
6. 주문이 취소되면 배달이 취소된다
7. 고객이 주문상태를 중간중간 조회한다
8. 주문상태가 바뀔 때 마다 카톡으로 알림을 보낸다
비기능적 요구사항
1. 트랜잭션
-
- 결제가 되지 않은 주문건은 아예 거래가 성립되지 않아야 한다 Sync 호출
- 장애격리
-
- 상점관리 기능이 수행되지 않더라도 주문은 365일 24시간 받을 수 있어야 한다 Async (event-driven), Eventual Consistency
- 결제시스템이 과중되면 사용자를 잠시동안 받지 않고 결제를 잠시후에 하도록 유도한다 Circuit breaker, fallback
- 성능
-
- 고객이 자주 상점관리에서 확인할 수 있는 배달상태를 주문시스템(프론트엔드)에서 확인할 수 있어야 한다 CQRS
- 배달상태가 바뀔때마다 카톡 등으로 알림을 줄 수 있어야 한다 Event driven
체크포인트
- 분석 설계
- 이벤트스토밍:
- 스티커 색상별 객체의 의미를 제대로 이해하여 헥사고날 아키텍처와의 연계 설계에 적절히 반영하고 있는가?
- 각 도메인 이벤트가 의미있는 수준으로 정의되었는가?
- 어그리게잇: Command와 Event 들을 ACID 트랜잭션 단위의 Aggregate 로 제대로 묶었는가?
- 기능적 요구사항과 비기능적 요구사항을 누락 없이 반영하였는가?
- 서브 도메인, 바운디드 컨텍스트 분리
- 팀별 KPI 와 관심사, 상이한 배포주기 등에 따른 Sub-domain 이나 Bounded Context 를 적절히 분리하였고 그 분리 기준의 합리성이 충분히 설명되는가?
- 적어도 3개 이상 서비스 분리
- 폴리글랏 설계: 각 마이크로 서비스들의 구현 목표와 기능 특성에 따른 각자의 기술 Stack 과 저장소 구조를 다양하게 채택하여 설계하였는가?
- 서비스 시나리오 중 ACID 트랜잭션이 크리티컬한 Use 케이스에 대하여 무리하게 서비스가 과다하게 조밀히 분리되지 않았는가?
- 팀별 KPI 와 관심사, 상이한 배포주기 등에 따른 Sub-domain 이나 Bounded Context 를 적절히 분리하였고 그 분리 기준의 합리성이 충분히 설명되는가?
- 컨텍스트 매핑 / 이벤트 드리븐 아키텍처
- 업무 중요성과 도메인간 서열을 구분할 수 있는가? (Core, Supporting, General Domain)
- Request-Response 방식과 이벤트 드리븐 방식을 구분하여 설계할 수 있는가?
- 장애격리: 서포팅 서비스를 제거 하여도 기존 서비스에 영향이 없도록 설계하였는가?
- 신규 서비스를 추가 하였을때 기존 서비스의 데이터베이스에 영향이 없도록 설계(열려있는 아키택처)할 수 있는가?
- 이벤트와 폴리시를 연결하기 위한 Correlation-key 연결을 제대로 설계하였는가?
- 헥사고날 아키텍처
- 설계 결과에 따른 헥사고날 아키텍처 다이어그램을 제대로 그렸는가?
- 구현
- [DDD] 분석단계에서의 스티커별 색상과 헥사고날 아키텍처에 따라 구현체가 매핑되게 개발되었는가?
- Entity Pattern 과 Repository Pattern 을 적용하여 JPA 를 통하여 데이터 접근 어댑터를 개발하였는가
- [헥사고날 아키텍처] REST Inbound adaptor 이외에 gRPC 등의 Inbound Adaptor 를 추가함에 있어서 도메인 모델의 손상을 주지 않고 새로운 프로토콜에 기존 구현체를 적응시킬 수 있는가?
- 분석단계에서의 유비쿼터스 랭귀지 (업무현장에서 쓰는 용어) 를 사용하여 소스코드가 서술되었는가?
- Request-Response 방식의 서비스 중심 아키텍처 구현
- 마이크로 서비스간 Request-Response 호출에 있어 대상 서비스를 어떠한 방식으로 찾아서 호출 하였는가? (Service Discovery, REST, FeignClient)
- 서킷브레이커를 통하여 장애를 격리시킬 수 있는가?
- 이벤트 드리븐 아키텍처의 구현
- 카프카를 이용하여 PubSub 으로 하나 이상의 서비스가 연동되었는가?
- Correlation-key: 각 이벤트 건 (메시지)가 어떠한 폴리시를 처리할때 어떤 건에 연결된 처리건인지를 구별하기 위한 Correlation-key 연결을 제대로 구현 하였는가?
- Message Consumer 마이크로서비스가 장애상황에서 수신받지 못했던 기존 이벤트들을 다시 수신받아 처리하는가?
- Scaling-out: Message Consumer 마이크로서비스의 Replica 를 추가했을때 중복없이 이벤트를 수신할 수 있는가
- CQRS: Materialized View 를 구현하여, 타 마이크로서비스의 데이터 원본에 접근없이(Composite 서비스나 조인SQL 등 없이) 도 내 서비스의 화면 구성과 잦은 조회가 가능한가?
- 폴리글랏 플로그래밍
- 각 마이크로 서비스들이 하나이상의 각자의 기술 Stack 으로 구성되었는가?
- 각 마이크로 서비스들이 각자의 저장소 구조를 자율적으로 채택하고 각자의 저장소 유형 (RDB, NoSQL, File System 등)을 선택하여 구현하였는가?
- API 게이트웨이 (API Gateway)
- API GW를 통하여 마이크로 서비스들의 집입점을 통일할 수 있는가?
- 게이트웨이와 인증서버(OAuth), JWT 토큰 인증을 통하여 마이크로서비스들을 보호할 수 있는가?
- https://nginxstore.com/blog/api-gateway/%eb%a7%88%ec%9d%b4%ed%81%ac%eb%a1%9c%ec%84%9c%eb%b9%84%ec%8a%a4-%ea%b5%ac%ec%b6%95%ec%9d%84-%ec%9c%84%ed%95%9c-api-gateway-%ed%8c%a8%ed%84%b4-%ec%82%ac%ec%9a%a9%ed%95%98%ea%b8%b0/
- [DDD] 분석단계에서의 스티커별 색상과 헥사고날 아키텍처에 따라 구현체가 매핑되게 개발되었는가?
- 운영
- SLA 준수
- 셀프힐링: Liveness Probe 를 통하여 어떠한 서비스의 health 상태가 지속적으로 저하됨에 따라 어떠한 임계치에서 pod 가 재생되는 것을 증명할 수 있는가?
- 서킷브레이커, 레이트리밋 등을 통한 장애격리와 성능효율을 높힐 수 있는가?
- 오토스케일러 (HPA) 를 설정하여 확장적 운영이 가능한가?
- 모니터링, 앨럿팅:
- 무정지 운영 CI/CD (10)
- Readiness Probe 의 설정과 Rolling update을 통하여 신규 버전이 완전히 서비스를 받을 수 있는 상태일때 신규버전의 서비스로 전환됨을 siege 등으로 증명
- Contract Test : 자동화된 경계 테스트를 통하여 구현 오류나 API 계약위반를 미리 차단 가능한가?
- SLA 준수
분석/설계시 고려사항 예시
- 강의 신청 시 결제처리 : 서비스는 강의를 제공하는 강사의 이익을 제공해야 하기 때문에 수강신청시 결제처리에 대해서는 Request-Response 방식 처리한다.
- 강의 관리 기능은 서비스 제공의 측면이 강하며, 한 번 등록 시 여러명이 학생들이 수강신청을 하기 때문에 수강신청(Front)에 대해 강의관리 서비스는 Async (event-driven), Eventual Consistency 방식으로 처리한다.
- 결제시스템이 과중되면 사용자를 잠시동안 받지 않고 결제를 잠시후에 하도록 유도한다 Circuit breaker를 사용하여
- 학생이 강의관리에서 확인할 수 있는 수강신청내용을 수강신청시스템(프론트엔드)에서 확인할 수 있어야 한다 CQRS
- 결제를 제외한 나머지 inter-microservice 트랜잭션: 모든 이벤트에 대해 데이터 일관성의 시점이 크리티컬하지 않은 모든 경우가 대부분이라 판단, Eventual Consistency 를 기본으로 채택함.
- 마이크로 서비스를 넘나드는 시나리오에 대한 트랜잭션 처리
- 고객 예약시 결제처리: 결제가 완료되지 않은 예약은 절대 받지 않는다고 결정하여, ACID 트랜잭션 적용. 예약 완료시 사전에 방 상태를 확인하는 것과 결제처리에 대해서는 Request-Response 방식 처리
- 결제 완료시 Host 연결 및 예약처리: reservation 에서 room 마이크로서비스로 예약요청이 전달되는 과정에 있어서 room 마이크로 서비스가 별도의 배포주기를 가지기 때문에 Eventual Consistency 방식으로 트랜잭션 처리함.
- 나머지 모든 inter-microservice 트랜잭션: 예약상태, 후기처리 등 모든 이벤트에 대해 데이터 일관성의 시점이 크리티컬하지 않은 모든 경우가 대부분이라 판단, Eventual Consistency 를 기본으로 채택함.
참조
MSA 기반의 표준프레임워크 템플릿 소개 : https://maven.egovframe.go.kr/publist/HDD1/public/event/20211210/8.표준프레임워크%20기반의%20MSA%20템플릿.pdf
Spring Cloud 기반의 Service Mesh 구현
또는
표준프레임워크 MSA 적용 개발 가이드 : https://www.egovframe.go.kr/home/ntt/nttRead.do?pagerOffset=0&searchKey=&searchValue=&menuNo=76&bbsId=171&nttId=1809
서버리스 아키텍처 설명 : 시스템 구축을 하루 만에? 효과적 AM을 위한 서버리스 활용법 – LG CNS 블로그
API Gateway
- 외부(External) 에 API Gateway를 위치하여 내부 서비스를 보호 및 제어
- API Gateway는 중앙집중형 아키텍처로, SPOF(Single Point Of Failure) 문제가 생길 수 있다.
- Gateway Proxy Pattern을 사용하여, 클라이언트는 내부 구현을 알 필요가 없다.
- 장점
- 인증/인가 공통 로직 사용 -> 유지보수 효율성 상승
- 엔드포인트 단순화 -> 사용자가 API Gateway가 라우팅해주는 모든 서비스 이용 가능
- 라우팅/로드밸런싱 기능 지원
- 서비스 디스커버리 필요 <- 수많은 서비스 생성/삭제, IP 변경 등의 디스커버리 필요
Service Mesh
- 내부 서비스 관리를 위해 사용
- 분산형 아키텍처로 SPOF 가 발생하지 않고 확장이 용이함
- Sidecar proxy pattern을 사용하여, 클라이언트의 코드에 서비스 주소를 찾는 방법, failover 관련 코드가 추가된다.
SAGA Pattern - Choreography vs Orchestration
다음 경우는 Orchestration 방식으로 Command/Reply 방식의 전환 필요함
- 타 MSA 저장 요청 후 그 리턴값을 사용하여 다음 스텝 진행
- 데이터가 저장되는 순서가 보장되어야 함
그 외 다음 경우는 Choreography 방식 의 Domain Event 방식 처리
- 여러개의 MSA에 저장하는데 순서 상관 없음
- 타 MSA에 저장 결과(실패)가 현재 업무처리에 영향이 없고, 재처리 가능함
CDC (Changed Data Capture)
- MSA 서비스 간 데이터 변경사항 복제
- 준실시간(5~10초) 이내 동기화 되어야 하는 업무 요건에는 적합하지 않음
ETL
- 배치 등의 성격을 갖는 서비스의 DB (또는 파일) 로부터 ADW 로 데이터 적재 등
- 전체 데이터를 delete & insert 하는 방식의 배치 테이블 등은 replication 부하가 가중되는 트랜잭션으로, ETL 연계가 적합함
- API first design
- Service Mesh
- 내부 구성 서비스 간 IPC
- API Gateway
- 단일 서비스 진입점, 인증서버(OAuth), JWT 토큰 인증/인가
- SAGA - Choreography vs Orchestration
- Backing Service
- Telemetry
- Centralized Logging - ELK
- SYNC 호출 (정합성)
- 장애격리 :
- 비동기 발행/구독, event-driven, message broker
- xx상태 변경시 메시지로 알림
- 1:N 의 여러 callee 서비스에게 event 를 전달하는 경우 유리
- BASE
- Circuit breaker
- A 서비스 과부하(장애)시에도 조회B 서비스는 제공되도록 A서비스 연결 안함
- 시스템 자체는 죽지 않지만, 일부 요청이 처리되지 않게 되므로, Scale Out 등으로 서비스 확장을 하도록 운영/설계 추가 필요
- failback
- 장애복구 후 미처리 이벤트(message) 를 처
- API Composition, CQRS
- 모든 객실의 예약 정보 등을 한번에 확인
- 반정규화
- CDC
- Aggregate : Command와 Event 들이 ACID 단위로 묶었는지?
- 반드시 단일 트랜잭션 내에서 처리되어야 하는 데이터 반영 요건에 해당
- Polyglot
- 각 서비스 설계/개발을 독립적으로 수행하고, 서비스 자체 아키텍처를 가지는 Polyglot 적용
- Core, Supporing, General Domain, Shared Kernel
- Correlation-Key
- event와 policy 를 잘 연결해야 함
- 헥사고날 아키텍처
- CQRS 시 Materialized View
- 빈번한/대량의 데이터를 다른 서비스의 데이터 원본에 조인하지 않고 빠르게 조회 가능
- MSA방법론
- Event Storming
- 후보서비스식별
- 서비스 연관 파악
- 서비스 정의
- Cloud Native 환경으로 전환
- 작은 단위 저장소
- 수평 확장 용이
- 장애 격리
- 분산 서비스 간 연동/연계
- 이벤트를 기반으로 처리함 또는 주기적 Polling
- KAFKA 와 같은 message queue 사용. 이때 kafka가 EAI (enterprise architecture integration) 를 대체함
- 변경된 데이터 저장이 필요한 서비스들이 구독하여 저장하거나, SAGA 패턴을 사용해서 CDC 저장
'IT > Study' 카테고리의 다른 글
MSA 서비스 구현 방법론 (0) | 2021.06.16 |
---|---|
IoT / oneM2M - 용어 정리 (0) | 2021.03.25 |