본문 바로가기
IT/Study

MSA가 어렵다고 하는 이유는 무엇일까

by blogger 2022. 3. 7.

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] 
 

마이크로서비스 - 위키백과, 우리 모두의 백과사전

마이크로서비스(microservice)는 애플리케이션을 느슨하게 결합된 서비스의 모임으로 구조화하는 서비스 지향 아키텍처(SOA) 스타일의 일종인 소프트웨어 개발 기법이다. 마이크로서비스 아키텍처

ko.wikipedia.org

 

 

또한 코로나라는 전대미문의 바이러스의 창궐과 함께 전세계적으로 발생하고 있는 폭발적인 트래픽을 감당하기에 보다 더 효율적이고 경제적인 아키텍처로 판단되어 선택되는 경우도 많아지고 있다. 

대표적인 예로 백신예약 시스템이 있다.
http://www.koit.co.kr/news/articleView.html?idxno=87638 

코로나19 사전예약시스템 개선 개념도. [자료=질병관리청, 출처 :  정보통신신문(http://www.koit.co.kr)]



COVID-19라는 홍역을 치루면서 시스템이 최소한 먹통은 되지 않아야 한다는 것을 사람들이 인식하기 시작했다. 시스템이 정상 동작을 하지 않더라고 최소한 사용자에게 에러 화면이라도 보여주어야 UX 관점에서 사람들에게 외면받고 버려지는 시스템이 되지 않을 수 있다.

이런 접속 장애보다는..

 

 

 

 

이런 접속 장애보다..

차라리 이런게..

 

 

 

 

 

 

 

 

이런 화면이 낫지 않을까?

 

 

 



더이상 사람들은 100% 완벽한 시스템/서비스를 원하지 않는다. 지금 당장 서비스가 불가하다면 적어도 왜 그런지(DB장애라던지), 언제쯤 서비스를 이용할 수 있는지, 대기는 얼마나 해야 하는지에 대한 명확한 안내가 제공되기를 원하며, 나아가 사용자의 피드백이 시스템에 빠른 기간내에 녹아드는 것을 더 선호하는 시대가 되었다.

출처: https://uxdesign.cc/why-we-need-agile-research-teams-18fccd6c3c8

 

마이크로 서비스, 즉 서비스를 잘게 나누어 놓으면 트래픽의 유연한 처리가 가능하다는 것이 가장 큰 장점이다. 서비스 단위가 작기 때문에 만일 서비스가 정상 동작을 하지 않는 상태가 된다면 해당 서비스를 기동 중지(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

 

서비스 경량화를 위한 MSA 설계 시 고려사항

서비스 경량화를 위한 MSA 설계 시 고려사항

www.samsungsds.com

https://devops.com/implementing-message-queue-in-kubernetes/

 

Best of 2019: Implementing Message Queue in Kubernetes

As we close out 2019, we at DevOps.com wanted to highlight the five most popular articles of the year. Following is the fourth in our weeklong series of

devops.com

https://www.samsungsds.com/kr/insights/1239180_4627.html

 

 

 


MSA 정의
 
비즈니스 변화와 성장 속도가 빨라짐에 따라 IT시스템이 그 속도에 따라갈 수 있도록 개발과 운영을 포괄하는 기술.
하나의 큰 어플리케이션을 여러개로 쪼개 구성하여, 독립 배포가 가능한 서비스들의 변경과 조합이 가능하도록 만든 아키텍처
 
- 모놀리식 아키텍처 : 한 덩어리도 뭉친 거대 단일 서비스. 하나의 프로젝트, 단일 패키지로 배포됨
ㄴ 배포, 테스트, 표준화 등의 관리 용이성
ㄴ 기능 간 높은 상호 의존성으로 신규 개발 추가 및 변경의 어려움
- 마이크로서비스 아키텍처 : 독립적이고 단순한 개별 서비스들로 구성
ㄴ 서비스 단위 빠른 개발과 배포가 용이하고, 고효율 저비용 Scale out 구조
ㄴ 분산 시스템 환경에서의 트랜잭션 보장, 테스트 및 배포, 관리가 복잡함
 
 
서비스 분리 기준
 
1. 업무중심
- 기술이 아닌 업무 중심의 단위
- 데이터 연관성(DDD) 관점, 업무 기능 관점
- 업무/서비스 간 결합도/영향도가 낮은 단위
- 신규/추가 업무, 변경이 잦은 업무
2. 확장성/장애대응, 독립성/배포
- 서비스로 분리하면 큰 혜택을 볼 수 있는 단위 (확장성, 부하/장애 대응, 독립성 등)
- 장애 격리, 빠른 장애 대응으로 비즈니스 피해를 최소화 할 수 있는 단위
- 개별 실행 환경을 구축함으로써 독립적으로 개발/빌드 배포 모니터링 등의 확장이 가능한 단위
3. 서비스 기능
- 서비스 별 최소한의 API를 노출 (구현 부분은 숨김, Encapsulation)하고 API 간 통신이 원활한 단위
- 라이브러리를 공유하거나 유사한 기능들은 하나의 서비스로 통합
4. 변경 가능성/성능
- 상대적으로 작은 서비스일수록 새로 구현해 교체하기 쉬움
- 서비스 간 프로세스 및 데이터 공유가 빈번한 경우 통합 (두 서비스를 동시에 변경해야 할 경우가 빈번한 경우)
- 서비스 간 분리로 인해 허용할 수 없는 수준으로 성능 저하가 예상되는 경우 통합
5. 트랜잭션과 일관성
- 서비스들을 너무 세분화한 경우 분산 트랜잭션 처리, 데이터 일관성/정합성을 고려한 단위
- 실시간 데이터 정합성이 중요한 경우 하나의 서비스로 통합
6. 최적의 기술
- 신기술 또는 업무 특성에 맞는 최적의 기술 적용이 유연한 단위
7. 조직
- one service per team
- 20~30명 이상 팀이 커지는 경우 팀 또는 서비스 분리
- 다른 팀에 독립적으로 작업하고 배포할 수 있어야 함

 

Business Agility (빠르고 다양한 사업환경 변화 및 고객의 요구사항에 적시 대응하여 비즈니스 경쟁력을 확보) 에 따라 분리
 
 
MSA 설계시 고려 사항
- 여러 서비스 간 데이터의 Command (저장) 및 Query (조회) 를 위한 추가 설계 필요
- 서비스 간의 상호작용과 협업이 강조, 구현 세부정보를 캡슐화하는 API 설계가 중요
- 각 서비스 설계/개발을 독립적으로 수행하고, 서비스 자체 아키텍처를 가지는 Polyglot 적용
 
 
Microservice Design (4)
 
1. API First Design
- 변경을 최소화할 수 있는 안정적이고 견고한 API 설계를 위함
- API를 제공하는 Provider, API를 사용하는 consumer 가 협업하여 provider/consumer driven design
 
 
2. 분산 트랜잭션 설계
- 마이크로서비스 간 분산트랜잭션 및 보상트랜잭션 설계
- 분산 트랜잭션 디자인 패턴 (Saga) 를 활용한 orchestration/choreography 방식의 분선 트랜잭션 설계 (4.4.3)
- 순간적인 정합성은 안 맞을 수 있어도 최종 데이터 정합성은 맞도록(eventually consistent) 설계
 
 
SAGA 패턴은 코레오그래피(Choreography)와 오케스트레이션(Orchestration) 방식으로 구현할 수 있습니다. 코레오그래피는 분산 구조로 서비스 간에 비동기 연계를 통한 이벤트 방식이고 오케스트레이션은 전체 트랜잭션을 관장하는 코디네이터(Coordinator)를 두고 이를 통해 보상 거래를 처리하는 방식입니다. 스프링 부트(Spring Boot)와 카프카(Kafka)를 활용하여 각각의 방식을 구현할 수 있습니다.

SAGA 패턴은 애플리케이션 레벨에서 수행하고 2PC·CDC(change data capture)는 시스템 소프트웨어가 담당하느냐의 차이가 있을 뿐 궁극적인 실행 결과는 동일합니다. SAGA 패턴은 표현력이 더 넓어서 보상 트랜잭션 구성 방식에 따라 2PC와 CDC의 효과를 모두 낼 수 있습니다. 다만 모든 보상 트랜잭션을 완벽하게 구성하는 것이 현실적으로 어려울 수 있으며 단계별 에러 케이스를 다 검증해야 하는 부담이 있습니다. 강한 정합성(Strong Consistency)은 2PC만 보장할 수 있습니다. 반드시 반영되어야 하는 케이스인데 SAGA 패턴으로 보상 거래를 기술하기 복잡하다면 CDC가 구성이 단순하고 안정적이므로 더 적합하다고 할 수 있습니다.
 
 
 
3. API Composition
- 여러 서비스 API 호출 결과를 조합 하여 response 하는 형태
- 성능을 고려한 여러 서비스간의 호출 메커니즘 설계
- API Composition 디자인 패턴 (CQRS) 를 활용한 Command와 Query 의 책임을 분리하여 설계
- CQRS 적용 방법 : Read하는 엔드포인트를 따로 만들거나, Read Replica를 만든다거나, Read DB 앞에만 Cache를 설정한다거나, 인덱스를 Read나 CUD에 최적화되도록 설정
- 높은 수준의 CQRS 패턴은 Event Sourcing과 함께, Queue(AWS SQS, RabbitMQ, Kafka와 같은 Message Queue가 일반적이다)를 이용하여 비동기적으로 데이터를 쓰고 읽어오는 것이 일반적이다.
 
 
4. 동기/비동기 설계
- 서비스 독립성을 고려한 비동기 호출 설계
- 3가지 유형(통보, 요청/비동기 응답, 발행/구독) 설계
- 비동기는 동기호출방식에 비해 복잡하지만, callee로부터 응답을 대기하지 않고 다음 작업 가능 --> 응답시간이 길어지는 경우 유리
- callee 서비스가 가용상태가 아니더라도 caller 서비스는 작동할 수 있는 장점으로 분산환경에서 비동기 방식을 선호함
 
 
4.1 비동기 발행/구독 (message broker)
- 주로 1:N 형태의 여러 callee 서비스들에게 event 전달하는 경우 유리함 (broadcasting)
- 수신자가 가용한 상태가 아니어도 message를 보내두면 수신자가 가능할 때 수신하여 처리하므로 전체적인 가용성 향상
 
 
 
 
안티 패턴 (5)
 
Circuit Breaker
- 분산 서비스들 간의 응답 대기를 위해 타임아웃을 설정할 때 과도한 응답대기 발생함
- 특정 시스템에 일정 횟수 이상 에러 반복되면 circuit을 open 하여 해당 시스템 호출하지 않는 전략
 
Replication 기술을 사용한 의존성 회피
- 공유에 의한 서비스 간 과도한 종속성 발생함
- 해결을 위해 DRY (don't repeat yourself) 원칙을 위반하고 특정 기능을 필요로 하는 모든 서비스에 공유 모듈을 복제해서 사용
- 복제를 통해 종속성을 줄이고 bounded context 형태를 유지 (단 변경 사항이 거의 없는 안정적인 공유 모듈에만 적용해야 함)
 
Asynchronous Event Pushing (데이터 펌프)
- 리포팅 데이터 획득 과정에서 서비스와 데이터 사이의 경계가 무너짐
- 각 서비스가 데이터 업데이트를 비동기로 전송하고, 수집 서비스가 보고서DB 업데이트
 
 
MSA 구성요소 (6)
 
1. API / Edge Gateway (External G/W)
- 공통 인증, 인가
- 단일 진입점, 부하 분산, API 로깅 등
2. Service Mesh
- 내부 구성 서비스 간 IPC 가 핵심
3. Container Mgnt
4. Backing Service (Message Queue, DB, Cache)
5. CI/CD Automation
6. Telemetry (진단, 모니터링)

 


MSA 아키텍처 모델링 및 실습 예제 1 - 숙소예약

 

 

 

숙소예약(AirBnB)

본 예제는 MSA/DDD/Event Storming/EDA 를 포괄하는 분석/설계/구현/운영 전단계를 커버하도록 구성한 예제입니다. 이는 클라우드 네이티브 애플리케이션의 개발에 요구되는 체크포인트들을 통과하기 위한 예시 답안을 포함합니다.

Table of contents

서비스 시나리오

AirBnB 커버하기

기능적 요구사항

  1. 호스트가 임대할 숙소를 등록/수정/삭제한다.
  2. 고객이 숙소를 선택하여 예약한다.
  3. 예약과 동시에 결제가 진행된다.
  4. 예약이 되면 예약 내역(Message)이 전달된다.
  5. 고객이 예약을 취소할 수 있다.
  6. 예약 사항이 취소될 경우 취소 내역(Message)이 전달된다.
  7. 숙소에 후기(review)를 남길 수 있다.
  8. 전체적인 숙소에 대한 정보 및 예약 상태 등을 한 화면에서 확인 할 수 있다.(viewpage)

비기능적 요구사항

  1. 트랜잭션
    1. 결제가 되지 않은 예약 건은 성립되지 않아야 한다. (Sync 호출)
  2. 장애격리
    1. 숙소 등록 및 메시지 전송 기능이 수행되지 않더라도 예약은 365일 24시간 받을 수 있어야 한다 Async (event-driven), Eventual Consistency
    2. 예약 시스템이 과중되면 사용자를 잠시동안 받지 않고 잠시 후에 하도록 유도한다 Circuit breaker, fallback
  3. 성능
    1. 모든 방에 대한 정보 및 예약 상태 등을 한번에 확인할 수 있어야 한다 (CQRS)
    2. 예약의 상태가 바뀔 때마다 메시지로 알림을 줄 수 있어야 한다 (Event driven)

체크포인트

  • 분석 설계
    • 이벤트스토밍:
      • 스티커 색상별 객체의 의미를 제대로 이해하여 헥사고날 아키텍처와의 연계 설계에 적절히 반영하고 있는가?
      • 각 도메인 이벤트가 의미있는 수준으로 정의되었는가?
      • 어그리게잇: Command와 Event 들을 ACID 트랜잭션 단위의 Aggregate 로 제대로 묶었는가?
      • 기능적 요구사항과 비기능적 요구사항을 누락 없이 반영하였는가?
    • 서브 도메인, 바운디드 컨텍스트 분리
      • 팀별 KPI 와 관심사, 상이한 배포주기 등에 따른 Sub-domain 이나 Bounded Context 를 적절히 분리하였고 그 분리 기준의 합리성이 충분히 설명되는가?
        • 적어도 3개 이상 서비스 분리
      • 폴리글랏 설계: 각 마이크로 서비스들의 구현 목표와 기능 특성에 따른 각자의 기술 Stack 과 저장소 구조를 다양하게 채택하여 설계하였는가?
      • 서비스 시나리오 중 ACID 트랜잭션이 크리티컬한 Use 케이스에 대하여 무리하게 서비스가 과다하게 조밀히 분리되지 않았는가?
    • 컨텍스트 매핑 / 이벤트 드리븐 아키텍처
      • 업무 중요성과 도메인간 서열을 구분할 수 있는가? (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 토큰 인증을 통하여 마이크로서비스들을 보호할 수 있는가?
  • 운영
    • SLA 준수
      • 셀프힐링: Liveness Probe 를 통하여 어떠한 서비스의 health 상태가 지속적으로 저하됨에 따라 어떠한 임계치에서 pod 가 재생되는 것을 증명할 수 있는가?
      • 서킷브레이커, 레이트리밋 등을 통한 장애격리와 성능효율을 높힐 수 있는가?
      • 오토스케일러 (HPA) 를 설정하여 확장적 운영이 가능한가?
      • 모니터링, 앨럿팅:
    • 무정지 운영 CI/CD (10)
      • Readiness Probe 의 설정과 Rolling update을 통하여 신규 버전이 완전히 서비스를 받을 수 있는 상태일때 신규버전의 서비스로 전환됨을 siege 등으로 증명
      • Contract Test : 자동화된 경계 테스트를 통하여 구현 오류나 API 계약위반를 미리 차단 가능한가?
 
  • 마이크로 서비스를 넘나드는 시나리오에 대한 트랜잭션 처리
  • 고객 예약시 결제처리: 결제가 완료되지 않은 예약은 절대 받지 않는다고 결정하여, 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. 트랜잭션

    1. 결제가 되지 않은 주문건은 아예 거래가 성립되지 않아야 한다 Sync 호출
  1. 장애격리
    1. 상점관리 기능이 수행되지 않더라도 주문은 365일 24시간 받을 수 있어야 한다 Async (event-driven), Eventual Consistency
    1. 결제시스템이 과중되면 사용자를 잠시동안 받지 않고 결제를 잠시후에 하도록 유도한다 Circuit breaker, fallback
  1. 성능
    1. 고객이 자주 상점관리에서 확인할 수 있는 배달상태를 주문시스템(프론트엔드)에서 확인할 수 있어야 한다 CQRS
    1. 배달상태가 바뀔때마다 카톡 등으로 알림을 줄 수 있어야 한다 Event driven

체크포인트

  • 분석 설계
  • 이벤트스토밍:
    • 스티커 색상별 객체의 의미를 제대로 이해하여 헥사고날 아키텍처와의 연계 설계에 적절히 반영하고 있는가?
    • 각 도메인 이벤트가 의미있는 수준으로 정의되었는가?
    • 어그리게잇: Command와 Event 들을 ACID 트랜잭션 단위의 Aggregate 로 제대로 묶었는가?
    • 기능적 요구사항과 비기능적 요구사항을 누락 없이 반영하였는가?
  • 서브 도메인, 바운디드 컨텍스트 분리
    • 팀별 KPI 와 관심사, 상이한 배포주기 등에 따른 Sub-domain 이나 Bounded Context 를 적절히 분리하였고 그 분리 기준의 합리성이 충분히 설명되는가?
      • 적어도 3개 이상 서비스 분리
    • 폴리글랏 설계: 각 마이크로 서비스들의 구현 목표와 기능 특성에 따른 각자의 기술 Stack 과 저장소 구조를 다양하게 채택하여 설계하였는가?
    • 서비스 시나리오 중 ACID 트랜잭션이 크리티컬한 Use 케이스에 대하여 무리하게 서비스가 과다하게 조밀히 분리되지 않았는가?
  • 컨텍스트 매핑 / 이벤트 드리븐 아키텍처
    • 업무 중요성과 도메인간 서열을 구분할 수 있는가? (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)
  • 운영
    • SLA 준수
      • 셀프힐링: Liveness Probe 를 통하여 어떠한 서비스의 health 상태가 지속적으로 저하됨에 따라 어떠한 임계치에서 pod 가 재생되는 것을 증명할 수 있는가?
      • 서킷브레이커, 레이트리밋 등을 통한 장애격리와 성능효율을 높힐 수 있는가?
      • 오토스케일러 (HPA) 를 설정하여 확장적 운영이 가능한가?
      • 모니터링, 앨럿팅:
    • 무정지 운영 CI/CD (10)
      • Readiness Probe 의 설정과 Rolling update을 통하여 신규 버전이 완전히 서비스를 받을 수 있는 상태일때 신규버전의 서비스로 전환됨을 siege 등으로 증명
      • Contract Test : 자동화된 경계 테스트를 통하여 구현 오류나 API 계약위반를 미리 차단 가능한가?

분석/설계시 고려사항 예시

 

- 강의 신청 시 결제처리 : 서비스는 강의를 제공하는 강사의 이익을 제공해야 하기 때문에 수강신청시 결제처리에 대해서는  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에 저장 결과(실패)가 현재 업무처리에 영향이 없고, 재처리 가능함

SAGA 예시

 

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