업데이트
This commit is contained in:
104
README.md
104
README.md
@@ -8,23 +8,23 @@
|
||||
# Table of contents
|
||||
|
||||
- [예제 - 음식배달](#---)
|
||||
- [서비스 시나리오](#-)
|
||||
- [체크포인트](#)
|
||||
- [분석/설계](#)
|
||||
- [구현:](#)
|
||||
- [DDD 의 적용](#ddd--)
|
||||
- [폴리글랏 퍼시스턴스](#-)
|
||||
- [폴리글랏 프로그래밍](#-)
|
||||
- [동기식 호출 과 Fallback 처리](#---fallback-)
|
||||
- [비동기식 호출 / 시간적 디커플링 / 장애격리 / 최종 (Eventual) 일관성 테스트](#---------eventual--)
|
||||
- [서비스 시나리오](#서비스 시나리오)
|
||||
- [체크포인트](#체크포인트)
|
||||
- [분석/설계](#분석설계)
|
||||
- [구현:](#구현-)
|
||||
- [DDD 의 적용](#ddd-의-적용)
|
||||
- [폴리글랏 퍼시스턴스](#폴리글랏-퍼시스턴스)
|
||||
- [폴리글랏 프로그래밍](#폴리글랏-프로그래밍)
|
||||
- [동기식 호출 과 Fallback 처리](#동기식-호출-과-Fallback-처리)
|
||||
- [비동기식 호출 과 Eventual Consistency](#비동기식-호출-과-Eventual-Consistency)
|
||||
- [운영](#운영)
|
||||
- [CI/CD 설정](#cicd-)
|
||||
- [동기식 호출 / 서킷 브레이킹 / 장애격리](#------)
|
||||
- [오토스케일 아웃](#-)
|
||||
- [무정지 재배포](#-)
|
||||
- [신규 개발 조직의 추가](#---)
|
||||
- [CI/CD 설정](#cicd설정)
|
||||
- [동기식 호출 / 서킷 브레이킹 / 장애격리](#동기식-호출-서킷-브레이킹-장애격리)
|
||||
- [오토스케일 아웃](#오토스케일-아웃)
|
||||
- [무정지 재배포](#무정지-재배포)
|
||||
- [신규 개발 조직의 추가](#신규-개발-조직의-추가)
|
||||
|
||||
## 서비스 시나리오
|
||||
# 서비스 시나리오
|
||||
|
||||
배달의 민족 커버하기 - https://1sung.tistory.com/106
|
||||
|
||||
@@ -49,9 +49,11 @@
|
||||
1. 배달상태가 바뀔때마다 카톡 등으로 알림을 줄 수 있어야 한다 Event driven
|
||||
|
||||
|
||||
## 체크포인트
|
||||
# 체크포인트
|
||||
|
||||
- 분석 설계
|
||||
|
||||
|
||||
- 이벤트스토밍:
|
||||
- 스티커 색상별 객체의 의미를 제대로 이해하여 헥사고날 아키텍처와의 연계 설계에 적절히 반영하고 있는가?
|
||||
- 각 도메인 이벤트가 의미있는 수준으로 정의되었는가?
|
||||
@@ -69,6 +71,7 @@
|
||||
- 장애격리: 서포팅 서비스를 제거 하여도 기존 서비스에 영향이 없도록 설계하였는가?
|
||||
- 신규 서비스를 추가 하였을때 기존 서비스의 데이터베이스에 영향이 없도록 설계(열려있는 아키택처)할 수 있는가?
|
||||
- 이벤트와 폴리시를 연결하기 위한 Correlation-key 연결을 제대로 설계하였는가?
|
||||
|
||||
- 헥사고날 아키텍처
|
||||
- 설계 결과에 따른 헥사고날 아키텍처 다이어그램을 제대로 그렸는가?
|
||||
|
||||
@@ -104,30 +107,49 @@
|
||||
- Contract Test : 자동화된 경계 테스트를 통하여 구현 오류나 API 계약위반를 미리 차단 가능한가?
|
||||
|
||||
|
||||
## 분석/설계
|
||||
# 분석/설계
|
||||
|
||||
|
||||
* 이벤트스토밍 결과: http://msaez.io/#/storming/nZJ2QhwVc4NlVJPbtTkZ8x9jclF2/every/a77281d704710b0c2e6a823b6e6d973a/-M5AV2z--su_i4BfQfeF
|
||||
|
||||
- 조직분석
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
|
||||
- 과정중 도출된 잘못된 도메인 이벤트들을 걸러내는 작업을 수행함
|
||||
- 주문시>메뉴카테고리선택됨, 주문시>메뉴검색됨 : UI 의 이벤트이지, 업무적인 의미의 이벤트가 아니라서 제외
|
||||
|
||||
- 어그리게잇: app의 Order, store 의 주문처리, 결제의 결제이력은 그와 연결된 command 와 event 들에 의하여 트랜잭션이 유지되어야 하는 단위임.
|
||||
|
||||

|
||||

|
||||
|
||||
- 비기능적 요구사항에 대한 반영 - 컨테스트 매핑/이벤트 드리븐 설계
|
||||
- 도메인 서열 분리
|
||||
- Core Domain: app(front), store : 없어서는 안될 핵심 서비스이며, 연견 Up-time SLA 수준을 99.999% 목표, 배포주기는 app 의 경우 1주일 1회 미만, store 의 경우 1개월 1회 미만
|
||||
- Supporting Domain: marketing, customer : 경쟁력을 내기위한 서비스이며, SLA 수준은 연간 60% 이상 uptime 목표, 배포주기는 각 팀의 자율이나 표준 스프린트 주기가 1주일 이므로 1주일 1회 이상을 기준으로 함.
|
||||
- General Domain: pay : 결제서비스로 3rd Party 외부 서비스를 사용하는 것이 경쟁력이 높음 (핑크색으로 이후 전환할 예정)
|
||||
- 마이크로 서비스를 넘나드는 시나리오에 대한 트랜잭션 처리
|
||||
- 고객 주문시 결제처리: 결제가 완료되지 않은 주문은 절대 받지 않는다는 경영자의 오랜 신념(?) 에 따라, ACID 트랜잭션 적용. 주문와료시 결제처리에 대해서는 Request-Response 방식 처리
|
||||
- 결제 완료시 점주연결 및 배송처리: App(front) 에서 Store 마이크로서비스로 주문요청이 전달되는 과정에 있어서 Store 마이크로 서비스가 별도의 배포주기를 가지기 때문에 Eventual Consistency 방식으로 트랜잭션 처리함.
|
||||
- 나머지 모든 inter-microservice 트랜잭션: 주문상태, 배달상태 등 모든 이벤트에 대해 카톡을 처리하는 등, 데이터 일관성의 시점이 크리티컬하지 않은 모든 경우가 대부분이라 판단, Eventual Consistency 를 기본으로 채택함.
|
||||
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
- 헥사고날 아키텍처 다이어그램 도출
|
||||
-
|
||||
- 헥사고날 아키텍처 다이어그램
|
||||
- Chris Richardson, MSA Patterns 참고하여 Inbound adaptor와 Outbound adaptor를 구분함
|
||||
- 호출관계에서 PubSub 과 Req/Resp 를 구분함
|
||||
-
|
||||
- 서브 도메인과 바운디드 컨텍스트의 분리: 각 팀의 KPI 별로 아래와 같이 관심 구현 스토리를 나눠가짐
|
||||
- ...
|
||||
- 도메인 서열 분리
|
||||
- Core Domain: app(front), store : 없어서는 안될 핵심 서비스이며, 연견 Up-time SLA 수준을 99.999% 목표, 배포주기는 app 의 경우 1주일 1회 미만, store 의 경우 1개월 1회 미만
|
||||
- Supporting Domain: marketing, customer : 경쟁력을 내기위한 서비스이며, SLA 수준은 연간 60% 이상 uptime 목표, 배포주기는 각 팀의 자율이나 표준 스프린트 주기가 1주일 이므로 1주일 1회 이상을 기준으로 함.
|
||||
- General Domain: pay : 결제서비스로 3rd Party 외부 서비스를 사용하는 것이 경쟁력이 높음 (핑크색으로 이후 전환할 예정)
|
||||
- 마이크로 서비스를 넘나드는 시나리오에 대한 트랜잭션 처리
|
||||
- 고객 주문시 결제처리: 결제가 완료되지 않은 주문은 절대 받지 않는다는 경영자의 오랜 신념(?) 에 따라, ACID 트랜잭션 적용. 주문와료시 결제처리에 대해서는 Request-Response 방식 처리
|
||||
- 결제 완료시 점주연결 및 배송처리: App(front) 에서 Store 마이크로서비스로 주문요청이 전달되는 과정에 있어서 Store 마이크로 서비스가 별도의 배포주기를 가지기 때문에 Eventual Consistency 방식으로 트랜잭션 처리함.
|
||||
- 나머지 모든 inter-microservice 트랜잭션: 주문상태, 배달상태 등 모든 이벤트에 대해 카톡을 처리하는 등, 데이터 일관성의 시점이 크리티컬하지 않은 모든 경우가 대부분이라 판단, Eventual Consistency 를 기본으로 채택함.
|
||||
- 서브 도메인과 바운디드 컨텍스트의 분리: 각 팀의 KPI 별로 아래와 같이 관심 구현 스토리를 나눠가짐
|
||||
|
||||
|
||||
## 구현:
|
||||
# 구현:
|
||||
|
||||
분석/설계 단계에서 도출된 헥사고날 아키텍처에 따라, 각 BC별로 대변되는 마이크로 서비스들을 스프링부트와 파이선으로 구현하였다. 구현한 각 서비스를 로컬에서 실행하는 방법은 아래와 같다 (각자의 포트넘버는 8081 ~ 808n 이다)
|
||||
|
||||
@@ -142,7 +164,7 @@ cd customer
|
||||
python policy-handler.py # 파이썬
|
||||
```
|
||||
|
||||
### DDD 의 적용
|
||||
## DDD 의 적용
|
||||
|
||||
- 각 서비스내에 도출된 핵심 Aggregate Root 객체를 Entity 로 선언하였다: (예시는 pay 마이크로 서비스). 이때 가능한 현업에서 사용하는 언어 (유비쿼터스 랭귀지)를 그대로 사용하려고 노력했다. 하지만, 일부 구현에 있어서 영문이 아닌 경우는 실행이 불가능한 경우가 있기 때문에 계속 사용할 방법은 아닌것 같다. (Maven pom.xml, Kafka의 topic id, FeignClient 의 서비스 id 등은 한글로 식별자를 사용하는 경우 오류가 발생하는 것을 확인하였다)
|
||||
|
||||
@@ -211,7 +233,7 @@ http localhost:8081/orders/1
|
||||
```
|
||||
|
||||
|
||||
### 폴리글랏 퍼시스턴스
|
||||
## 폴리글랏 퍼시스턴스
|
||||
|
||||
앱프런트 (app) 는 서비스 특성상 많은 사용자의 유입과 상품 정보의 다양한 콘텐츠를 저장해야 하는 특징으로 인해 RDB 보다는 Document DB / NoSQL 계열의 데이터베이스인 Mongo DB 를 사용하기로 하였다. 이를 위해 order 의 선언에는 @Entity 가 아닌 @Document 로 마킹되었으며, 별다른 작업없이 기존의 Entity Pattern 과 Repository Pattern 적용과 데이터베이스 제품의 설정 (application.yml) 만으로 MongoDB 에 부착시켰다
|
||||
|
||||
@@ -231,7 +253,7 @@ MongoDB 를 이후 운영단계에서도 사용할 수 있게 하기 위해서 d
|
||||
```
|
||||
```
|
||||
|
||||
### 폴리글랏 프로그래밍
|
||||
## 폴리글랏 프로그래밍
|
||||
|
||||
고객관리 서비스(customer)의 시나리오인 주문상태, 배달상태 변경에 따라 고객에게 카톡메시지 보내는 기능의 구현 파트는 해당 팀이 python 을 이용하여 구현하기로 하였다. 해당 파이썬 구현체는 각 이벤트를 수신하여 처리하는 Kafka consumer 로 구현되었고 코드는 다음과 같다:
|
||||
```
|
||||
@@ -266,7 +288,7 @@ CMD ["python", "policy-handler.py"]
|
||||
```
|
||||
|
||||
|
||||
### 동기식 호출 과 Fallback 처리
|
||||
## 동기식 호출 과 Fallback 처리
|
||||
|
||||
분석단계에서의 조건 중 하나로 주문(app)->결제(pay) 간의 호출은 동기식 일관성을 유지하는 트랜잭션으로 처리하기로 하였다. 호출 프로토콜은 이미 앞서 Rest Repository 에 의해 노출되어있는 REST 서비스를 FeignClient 를 이용하여 호출하도록 한다.
|
||||
|
||||
@@ -325,7 +347,7 @@ http localhost:8081/orders item=피자 storeId=2 #Success
|
||||
|
||||
|
||||
|
||||
### 비동기식 호출 / 시간적 디커플링 / 장애격리 / 최종 (Eventual) 일관성 테스트
|
||||
## 비동기식 호출 / 시간적 디커플링 / 장애격리 / 최종 (Eventual) 일관성 테스트
|
||||
|
||||
|
||||
결제가 이루어진 후에 상점시스템으로 이를 알려주는 행위는 동기식이 아니라 비 동기식으로 처리하여 상점 시스템의 처리를 위하여 결제주문이 블로킹 되지 않아도록 처리한다.
|
||||
@@ -411,15 +433,15 @@ http localhost:8080/orders # 모든 주문의 상태가 "배송됨"으로
|
||||
```
|
||||
|
||||
|
||||
## 운영
|
||||
# 운영
|
||||
|
||||
### CI/CD 설정
|
||||
## CI/CD 설정
|
||||
|
||||
|
||||
각 구현체들은 각자의 source repository 에 구성되었고, 사용한 CI/CD 플랫폼은 GCP를 사용하였으며, pipeline build script 는 각 프로젝트 폴더 이하에 cloudbuild.yml 에 포함되었다.
|
||||
|
||||
|
||||
### 동기식 호출 / 서킷 브레이킹 / 장애격리
|
||||
## 동기식 호출 / 서킷 브레이킹 / 장애격리
|
||||
|
||||
* 서킷 브레이킹 프레임워크의 선택: Spring FeignClient + Hystrix 옵션을 사용하여 구현함
|
||||
|
||||
@@ -631,7 +653,7 @@ Concurrency: 96.02
|
||||
```
|
||||
|
||||
|
||||
### 무정지 재배포
|
||||
## 무정지 재배포
|
||||
|
||||
* 먼저 무정지 재배포가 100% 되는 것인지 확인하기 위해서 Autoscaler 이나 CB 설정을 제거함
|
||||
|
||||
@@ -693,7 +715,9 @@ Concurrency: 96.02
|
||||
배포기간 동안 Availability 가 변화없기 때문에 무정지 재배포가 성공한 것으로 확인됨.
|
||||
|
||||
|
||||
## 신규 개발 조직의 추가
|
||||
# 신규 개발 조직의 추가
|
||||
|
||||

|
||||
|
||||
- 마케팅팀의 추가
|
||||
- KPI: 신규 고객의 유입률 증대와 기존 고객의 충성도 향상
|
||||
|
||||
Reference in New Issue
Block a user