도메인 주도 설계로 시작하는 마이크로서비스 개발
created : 2021-07-21T17:56:55+00:00
modified : 2021-11-28T18:00:30+00:00
1. 아마존 비지니스 민첩성의 비밀
1.1 성공한 인터넷 기업들과 비지니스 민첩성
- Amazon, Netflix, Uber
- 아마존 배포 속도 : 11.6초 마다 아마존 쇼핑몰의 소스코드가 변경되어 배포된다.
- 클라우드 인프라의 등장 : AWS(Amazon Web Service), Azure, GCP(Google Cloud Platform)
- 스케일 업과 스케일 아웃:
- 스케일업은 기존 시스템 자체의 물리적 용량을 증가시켜 성능을 높이는 방법이다. 사용량이 많아지는 것은 데이터 처리가 증가한다는 것이고 시스템을 담을 그릇도 커져야 한다.
- 스케일 아웃은 기존 시스템과 용량이 같은 다수의 장비를 병행 추가해서 가용성을 높이는 방법이다. 즉, 사용량을 분산시켜 전체적으로 장애 없이 운영되게 한다.
- 클라우드 프렌들리와 클라우드 네이티브:
- Cloud Friendly Application : 큰 덩어리로 클라우드 환경에 올라갈 수 있게만 한 어플리케이션
- Cloud Native Application : 독립적으로 분리되어 배포될 수 있는 조각으로 구성된 어플리케이션
- 필자는 클라우드 프렌들리에서 클라우드 네이티브로 전이해야한다고 주장
1.2 마이크로서비스란 무엇인가?
모노리스와 마이크로서비스 비교
- 모노리스(monolith):
- 하나의 단위로 개발되는 일체식 어플리케이션 보통은 3티어(3 tier)라고 불리는 사용자 인터페이스와 데이터베이스, 서버 어플리케이션으로 구성된다.
- 논리적인 단일체로서 아무리 작은 변화에도 새로운 버전으로 전체를 빌드해서 배포해야 한다.
- 로드 밸런서를 앞에 두고 여러 인스턴스 위에 큰 덩어리를 복제해 수평으로 확장한다.
- 마이크로서비스(microservice):
- 서버 측이 여러개의 조각으로 구성돼 각 서비스가 별개의 인스턴스로 로딩된다.
SOA와 마이크로서비스
- modulearity 개념의 발전 흐름:
- structured 방법론 -> CBD(Component Based Development) -> SOA(Service Oriented Architecture)
- SOA는 구체적이지 않고 이론적이다.
- MSA는 이러한 SOA가 클라우드 인프라의 등장으로 하드웨어를 유연하게 다룰 수 있게 되면서 비로소 실현되어 성공적으로 증명된 시스템 구조이다.
- Polyglot : 특정 서비스를 구축하는 데 사용되는 언어나 저장소를 자율적으로 선택할 수 있는 방식
- CBD/SOA 접근법에서는 어플리케이션은 모듈별로 분리했지만 저장소까지는 부리하지 못했다.
- MSA에서는:
- 서비스별 저장소를 분리해서 다른 서비스가 저장소를 직접 호출하지 못하도록 캡슐화한다. 즉, 다른 서비스의 저장소에 접근하는 수단은 API밖에 없다.
- REST API 같은 가벼운 개방형 표준을 사용해 각 서비스가 느슨하게 연계되고 누구나 쉽게 사용할 수 있다.
1.3 마이크로서비스를 위한 조건은 무엇인가?
조직의 변화: 업무 기능 중심 팀
- 콘웨이 법칙(Conway’s law) : 시스템을 개발할 때 항상 시스템의 모양이 팀의 의사소통 구조를 반영하는 것을 말한다.
- 마이크로서비스를 만드는 팀은 업무 기능 중심의 팀이여야 한다.
- two pizza team : 피자 두판으로 서로 빈번히 의사소통하며 함께 식사할 수 있는 정도의 팀원 수
관리체계의 변화: 자율적인 분권 거버넌스, 폴리글랏
- 각 팀별로 알아서 자율적으로 서비스 성격에 맞는 최적의 언어와 저장소를 자율적으로 선택한다.
개발 생명주기의 변화: 프로젝트가 아니라 제품 중심으로
- agile(애자일):
- 2~3주 단위의 Sprint(스프린트)
- 마이크로서비스느 계속 피드백을 받아 지속적으로 변화, 개선되고 향상되는 존재다.
개발 환경의 변화: 인프라 자동화
- 개발 환경 준비(인프라)
- 개발(분석/설계/개발)
- 개발지원과정(빌드/테스트/배포)
- 빌드/배포 파이프라인:
- 소스코드 빌드 -> 개발 환경 배포 -> 스테이징 환경 배포 -> 운영환경 배포
- Infrastructure as Code: 코드를 이용해 인프라 구성부터 애플리케이션 빌드, 배포를 정의하는 것
저장소의 변화: 통합 저장소가 아닌 분권 데이터 관리
- 데이터 일관성 처리:
- two-phase commit : 항상 모든 서비스가 지원하는 것은 아니다.
- 비동기 이벤트 처리를 통한 협업 -> 결과적 일관성(Eventual Consistency):
- 두 서비스의 데이터가 일시적으로 불일치하는 시점에 있고 일관성이 없는 상태이지만 결국에는 두 데이터가 같아진다는 개념이다.
위기 대응 방식의 변화: 실패를 고려한 설계
- 버너 보겔스(Werner Vogels) : 소프트웨어는 모두 실패한다.
- 내결함성(fault tolerance)
- 서킷 브레이커(circuit breaker) 패턴
1.4 정리
- 비즈니스 민첩성을 위한 3가지 요소:
- 점진 반복적인 개발 프로세스
- 유연하고 자동화된 개발 환경
- 자율적인 업무 기능 팀과 개발 문화
2. MSA의 이해
2.1 리액티브 선언: 현대 애플리케이션이 갖춰야 할 바람직한 속성들
- 리액티브 선언의 4가지 요소
- 응답성(Responsive) : 사용자에게 신뢰성 있는 응답을 빠르고 적절하게 제공하는 것
- 탄력성(Resilient) : 장애가 발생하거나 부분적으로 고장나더라도 시스템 전체가 고장나지 않고 빠르게 복구하는 능력
- 유연성(Elastic) : 시스템의 사용량에 변화가 있더라도 균일한 응답성을 제공하는 것을 의미, 시스템 사용량에 비례해서 자원을 늘리거나 줄이는 능력
- 메시지 기반(Message Driven) : 비동기 메시지 전달을 통해 위치 투명성, 느슨한 결합, 논블로킹 통신을 지향하는 것
- 아키텍쳐 유연성(Flexibility) : 메시지 기반이라는 요소로 이를 만족
2.2 결합에서 느슨한 결합의 아키텍처로의 변화
- 애플리케이션 개발 - 예시 : Spring
- 오케스트레이션 - 예시 : Kubernetes
- 런타임 - 예시 : docker
- 프로비저닝 - 예시 : Terraform
- IaaS - 예시 : aws
2.3 마이크로서비스의 외부 아키텍처와 내부 아키텍처
- 외부 아키텍처(outer architecture) : 인프라 영역과 플랫폼 영역, 애플리케이션 영역에 있는 구성요소 및 그것들의 관계를 정의하는 것
- 내부 아키택처(inner architecture) : 마이크로서비스가 제공하는 API, 비지니스 로직, 이벤트 발행, 데이터 저장 처리 등을 어떻게 구조화 해야하는가
2.4 MSA 구성요소 및 MSA 패턴
- 인프라 패턴, 애플리케이션 인프라 패턴, 애플리케이션 패턴 등으로 분류
- MSA 구성요소 및 패턴의 유형:
- 인프라 구성요소 : 마이크로서비스를 지탱하는 하부구조 인프라를 구축하는 데 필요한 구성요소
- 플랫폼 패턴 : 인프라 위에서 마이크로서비스의 운영과 관리를 지원하는 플랫폼 차원의 패턴
- 애플리케이션 패턴 : 마이크로서비스 애플리케이션을 구성하는 데 필요한 패턴
2.4.1 인프라 구성요소
- 퍼블릭 클라우드 vs 베어 메탈 vs 프라이빗 클라우드 환경:
- 퍼블릭 클라우드 : 클라우드 사업자가 서비스로 제공하는 퍼블릭 IaaS, PaaS 등
- 베어메탈 : 어떠한 소프트웨어도 담지 않은 하드웨어 서버 제품군 자체
- 프라이빗 클라우드 : 베어메탈에 직접 클라우드 서비스를 구축하는 것
- VM vs Container:
- VM : hypervisor 를 이용하여 하나의 시스템에서 여러개의 운영체제를 사용하는 기술
- Container : 컨테이너 엔진을 사용해 가상의 격리된 공간 생성:
- 이식성 : 어떠한 호스트 커널이나 플랫폼 버전에 상관 없이 도커만 실행할 수 있으면 사용 가능하며 동알하게 동작된다.
- 신속성 : 크기가 작고 가볍기 때문에 빠르게 배포 가능하며, 문제 발생 시 수정할 필요 없이 새로 기능하면 된다.
- 재사용성 : 동일한 환경을 재사용해서 쉽게 설정하기 때문에 개발, 테스트, 스테이징, 프로덕트 환경을 동일한 환경으로 구축하기가 쉽다.
- 컨테이너 오케스트레이션:
- 컨테이너의 자동 배치 및 복제, 장애 복구, 확장 및 축소, 컨테이너 간 통신, 로드 밸런싱 등의 컨테이너 관리를 위한 기능
- 도커 스웜(Docker Swarm), 아파치 메소스(Apache Mesos), 쿠버네티스(Kubernetes)
- 자동화된 자원 배정(Automatic binpacking) : 각 컨테이너가 필요로 하는 CPU와 메모리를 쿠버네티스에 요청하면 컨테이너를 노드에 맞춰 자동으로 배치한다.
- 셀프 치유(Self-healing) : 컨테이너의 이상 유무를 점검해서 실패한 경우 자동으로 교채하고 재스케줄링한다.
- 수평확장(Horizontal scaling) : 일정 CPU 및 메모리 사용량을 초과하면 자동으로 확장한다.
- 그 밖의 다양한 클라우드 인프라 서비스:
- AWS Elastic Beanstalk, AWS Elastic Container Service(ECS), Azure Web APp, Google App Engine
- IaaS, CaaS, PaaS:
- IaaS(Infrastructure as a Service): 가상 머신, 스토리지, 네트워크 같은 인프라를 필요한 만큼 적시에 지공하는 서비스:
- AWS EC2(Elastic Compute Cloud), GCP Compute Engine, Azure VM
- CaaS(Container as a Service) : 컨테이너 기반 가상화를 사용해 컨테이너를 업로드, 구성, 실행, 확장 중지할 수 있는 서비스:
- Azure Kubernetes Service(AKS), AWS Elastic Kubernetes Service(EKS), Google Kubernetes Engine(GKE), AWS ECS
- PaaS(Platform as Service) : 복잡함 없이 애플리케이션을 곧바로 개발, 실행, 관리할 수 있는 플랫폼 환경을 서비스 형태로 제공한다:
- Azuer Web App, Google App Engine, Cloud Foundry, Heroku, AWS Elastic Beanstalk
- IaaS(Infrastructure as a Service): 가상 머신, 스토리지, 네트워크 같은 인프라를 필요한 만큼 적시에 지공하는 서비스:
2.4.2 마이크로서비스 운영과 관리를 위한 플랫폼 패턴
- CI : 지속적 통함(Continuous Integration)
- CD : 지속적 서비스 제공(Continuous Delivery) or 지속적 배포(Continuous Deployment)
- 빌드/배포 파이프라인 설계:
- 리포지토리 -> 빌드&유닛 테스트 -> 정적 분석 -> 통합테스트 -> 배포 -> 마이크로서비스
- Infrastructure as Code
- 넷플릭스 OSS, Docker
- 스프링 클라우드: 스프링 부트 + 넷플릭스 OSS:
- 모든 마이크로서비스는 인프라에 종속되지 않도록 데이터베이스, 파일 등에 저장된 환경 설정 정보를 형상관리 시스템에 연계된 Config 서비스에서 가져와 설정 정보를 주입한 후 클라우드 인프라의 개별 인스턴스로 로딩된다.
- 로딩과 동시에 서비스 레지스트리에 자신의 서비스명과 클라우드 인프라부터 할당받은 물리 주소를 매핑해서 등록한다.
- 클라이언트가 API 게이트웨이를 통해 마이크로서비스에 접근하고, 이때 API 게이트웨이는 적절한 라우팅 및 부하 관리를 위한 로드 밸런싱 수행
- 또한 API 게이트웨이에서 클라이언트가 마이크로서비스에 접근하기 위한 주소를 알기 위해 서비스 레지스트리 검색을 통해 서비스의 위치를 가져온다.
- 동시에 API 게이트웨이는 클라이언트가 각 서비스에 접근할 수 있는 권한이 있는지 권한 서비스와 연계해 인증/인가 처리를 수행한다.
- 이러한 모든 마이크로서비스 간의 호출 흐름은 모니터링 서비스와 추적 서비스에 의해 모니터링 되고 추적된다.
- 다양한 서비스의 등록 및 탐색을 위한 서비스 레지스트리, 서비스 디스커버리 패턴:
- 서비스 디스커버리(Service Discovery) 패턴 : 클라이언트가 여러개의 마이크로서비스를 호출하기 위해서는 최적 경로를 찾아주는 라우팅 기능과 적절한 부하 분산을 위한 로드 밸런싱 기능이 제공되어야 한다. (Netflix OSS 같은 경우 Zuul, Ribbon)
- 서비스 레지스트리(Serivce Registry) 패턴 : 마이크로 서비스의 명칭과 유동적인 IP 정보를 매핑해서 보관할 저장소(Netflix OSS 같은 경우 Eureka)
- 서비스 단일 진입을 위한 API 게이트웨이 패턴:
- 레지스트리 서비스와 연계한 동적 라우팅, 로드 밸런싱보안: 권한 서비스와 연계한 인증/인가
- 로그 집계 서비스와 연계한 로깅, 예: API 소비자 정보, 요청/응답 데이터
- 메트릭(Metrics). 예: 에러율, 평균/최고 지연시간, 호출 빈도 등
- 트레이싱 서비스와 연계한 서비스 추적. 예: 트래킹 ID 기록
- 모니터링 서비스와 연계한 장애 격리(서킷 브레이커 패턴)
- 스크링 클라우드의 경우 Spring API Gateway Service, Kubernetes 같은 경우 Kubernetes& ingress resource
- BFF(Backend for Frontend) 패턴:
- API 게이트웨이와 같은 진입점을 하나로 두지 않고 프런트 엔드 유형에 따라 각각 두는 패턴
- 예시 : API gateway for web, API gateway for mobile app
- BFF 뒤쪽에 통합 API gateway 를 둠으로써 공통적인 인증/인가, 로깅 등의 처리를 통제하는 구조로 구성할 수도 있다.
- 외부 구성 저장소 패턴:
- Config 원칙 : 어플리케이션이 배포되는 환경(스테이징, 프로덕션, 개발, 테스트 환경)이 매번 달라지기 때문에 코드에서 사용하는 환경 설정 정보는 코드와 완전히 분리되어 관리해야 한다는 원칙
- Spring Cloud Config, Kubernetes ConfigMap
- 인증/인가 패턴:
- 중앙 집중식 세션 관리:
- 기존 모노리스 방식과 유사하게 각자의 서비스에 세션을 저장하지 않고 공유 저장소에 세션을 저장하고 모든 서비스가 동일한 사용자 데이터를 얻게 하는 것
- Redis, Memcached
- 클라이언트 토큰:
- 세션은 중앙 서버에 저장되고 토큰은 사용자의 브라우저에 저장된다. 토큰은 사용자의 신원 정보를 가지고 있고 서버로 요청을 보낼 때 전송되기 때문에 서버에서 인가 처리를 할 수 있다.
- JWT(JSON Web Token), RFC 7519
- API 게이트웨이를 사용한 클라이언트 토큰:
- 인증/인가를 처리하기 위한 별도의 전담 서비스를 만들어 기능을 위임(auth service)
- 중앙 집중식 세션 관리:
- 장애 및 실패 처리를 위한 서킷 브레이커 패턴:
- 시스템 과부하나 특정 서비스에 문제가 생겼을 때 자연스럽게 다른 정상적인 서비스로 요청 흐름이 변경 되게 하는 패턴
- 모니터링과 추적 패턴:
- Spring Cloude 에서는 Hystric Dashboard
- Zipkin 오픈 소스
- 중앙화된 로그 집계 패턴:
- Logs 원칙 : 로그를 이벤트 스트림(event stream)으로 처리해야 한다. 로그는 시작과 끝이 고정된 것이 아니라 서비스가 실행되는 동안 계속되는 흐름이다.
- ELK(Elasticsearch, Logstash, Kibana) 스택:
- Elasticsearch (분산형 검색 분석엔진) : 정형, 비정형, 우치 정보, 메트릭 등 원하는 방법으로 검색을 수행 결합 가능
- Logstash (로그 집합기) : 데이터 처리 파이프라인, 다양한 소스에서 동시에 데이터를 수집해 변환한 뒤 특정 보관소로 데이터를 보냄
- Kibana (시각화) : 히스토그램, 막대 그래프, 파이차트 등 표현, 위치 데이터, 시계열 분석, 그래프 관계 탐색 등 지원
- MSA 기술 변화 흐름:
- Netflix OSS, Spring Cloud, AWS IaaS -> Kubernetes, OpenShift -> Kubernetes + Istio
- 서비스 메시 패턴:
- MSA 문제 영역을 위한 기능을 비지니스 로직과 분리해서 네트워크 인프라 계층에서 수행하게 하는 것
- Istio 가 대표적인 구현체
- Sidecar 패턴 : 모든 서비스 컨테이너에 추가로 사이드카 컨테이너가 배포되는 패턴으로 각 서비스를 연계할 때 한 서비스가 다른 서비스를 직접 호출하지 않고 사이트카인 프록시를 통해서 연계해서 개발자가 별도 작업 없이 관리 및 운영에 대한 서비스 등을 적용할 수 있다.
- 주요 기능:
- 트래픽 관리(Traffic Management) : 동적 라우팅, 로드 밸런싱
- 보안: 보안 통신채널(TLS), 인증/인가/암호화
- 관측성(Observability) : 메트릭, 분산 트레이싱, 로깅
- 스프링 클라우드 및 넷플릭스 OSS와의 차별점:
- 애플리케이션 코드의 변경이 거의 없다.
- 폴리글랏 애플리케이션을 지원한다.
- 이스티오는 쿠버네티스와 완벽하게 통합된 환경을 지원한다.
2.4.3 애플리케이션 패턴
- UI 컴포지트(UI Composite) 패턴 또는 마이크로 프런트엔드(Micro Frontend)
- 마이크로서비스 통신 패턴:
- 동기 통신 방식 (REST API)
- 비동기 통신 방식:
- 메시지브로커(Message broker) : Apache Kafaka, RabbitMQ, ActiveMQ
- Producer - Consumer 구조
- AWS SQS, AWS SNS, Azure Event Hub, Azure Event Grid
- event driven architecture: publish & subscribe
- event driven architecture + asychronous communication -> event-driven microservice
- 저장소 분리 패턴:
- 모노리스 같은 경우 통합 저장소
- 마이크로서비스는 각 서비스에서 가지고 있고 API를 통해서만 접근:
- 정보 은닉, 폴리글랏 저장소
- 분산 트랜잭션 처리 패턴:
- Saga 패턴:
- 여러개의 분산도니 서비스를 하나의 트랜잭션으로 묶지 않고 각 로컬 트랜잭션과 보상 트랜잭션을 이용해 비지니스 및 데이터의 정합성을 맞추는 것.
- 데이터 일관성에 대한 생각의 전환: 결과적 일관성 - 어떤 비지니스는 데이터의 일관성이 실시간으로 맞지 않더라도 어느 일정 시점이 됐을 때 일관성을 만족해도 되는 것이 있다. -> 고가용성 극대화
- Saga 패턴:
- 읽기와 쓰기 분리 : CQRS 패턴:
- Command Query Responsibility Segregation : 명령 조회 책임 분리
- API 조합과 CQRS
- 쓰기 최적화: 이벤트 소싱 패턴:
- 사가 패턴, CQRS 패턴에서 비지니스 불일치를 피하기 위해서는 저장소에 저장하는 것과 메시지를 보내는 것이 원자성을 지녀야 한다. 즉, 저장소에 저장하는 일과 메시지를 보내는 작업이 언제나 완전하게 진행되어 함께 실행되어야 한다.
- 이벤트 소싱(event sourcing) 기법 : 객체 상태를 데이터 모델에 맞춰 계산하지 않고 상태 트랜잭션 자체를 저장하는 것
- 모든 트랜잭션을 처리하는 것이 부담스러울 경우 일정 시간마다 스냅숏을 저장하고 스냅숏 이후 트랜잭션만 처리
- CRUD에서 CR만 처리하면 교착 상태가 발생하지 않는다.
- Axon Framework, Eventuate
2.5 정리
- 현대 애플리케이션 아키텍처에 대해 요구하는 특성을 알아보기 위해 리액티브 선언을 살펴보면 주요 특성으로 응답성, 유연성, 탄력성, 메시지 기반 등이 요구된다는 것을 알 수 있다. 특히 이러한 요소들은 애플리케이션의 유연성을 강하게 요구한다.
- MSA 아키텍처는 기존의 벤더 중심의 강 결합 아키텍처에서 오픈소스 중심의 느슨한 결합의 아키텍쳐로 변화할 것을 요구한다.
- MSA 아키텍처는 마이크로서비스 외부의 구성을 위한 외부 아키텍처와 마이크로서비스 내부 정의를 위한 내부아키텍처로 구성된다.
- MSA 아키텍처 영역의 문제 해결 방식이 다양한 MSA 패턴으로 정리되고 있고, 인프라 구성요소, 플랫폼 운영 관리 패턴, 애플리케이션 연계와 관련된 패턴 등이 존재한다.
- 클라우드 인프라 구성요소로 가상머신, 컨테이너, 컨테이너 오케스트레이션 등이 고려된다.
- 마이크로서비스의 생태계 발전과 함께 마이크로서비스 운영 관리를 위한 플랫폼 패턴들이 탄생했다.
- 플랫폼 패턴으로 넷플릭스 OSS 기반의 애플리케이션을 활용한 패턴이 최초로 등장했고, 이를 발전시킨 패턴이 쿠버네티스, 이스티오 등의 기술로 발전해 오고 있다.
- 마이크로서비스 애플리케이션을 구성하고 연계하기 위해 UI 컴포지트, 통신 패턴, 이벤트 기반 아키텍쳐 등이 고려된다.
- 저장소 분리 등으로 인한 분산 트랜잭션의 근본적인 문제 등을 해결하기 위한 사가 패턴, CQRS, 이벤트 소싱 패턴 등이 고려된다.
3. 마이크로서비스 애플리케이션 아키텍처
- 애플리케이션 구조나 설계에 신경 쓰지 않고 오직 기능 구현에만 몰두한 소프트웨어들의 유지보수는 힘들다.
3.1 비지니스 로직은 어디에? - 관심사의 분리
- Rule, Flow, Concept 을 표현하는 용어 : 비지니스 로직
- 관심사의 분리(separation of concerns) : 시스템의 각 영역이 처리하는 관심사가 분리되어 잘 관리돼야 한다
- 객체지향 분석설계(OOAD : Object Oriented Analysis and Design) : 비지니스 로직을 누가봐도 이해하기 쉽게 구조화하는 객체 모델로 표현하는 것을 강조
- MDD(Model Driven Development)는 이해하지 못할 코드를 마구 양산했다.
- POJO(Plan Old Java Object) 지향의 스프링 프레임워크를 기반으로 한 정부의 전자정부표준 마저 SQL안에 모든 업무로직이 들어있는 경우가 대부분이다.
- 데이터베이스 중심 아키텍처의 문제점:
- 저장소를 변경하기 어렵다.
- 대부분의 성능이 데이터베이스에 의존한다.
- 스케일 아웃의 효과가 미비하다
3.2 헥사고날 아키텍처와 클린 아키텍처
- 레이어드 아키텍처:
- presentation : 화면 표현 및 전환 처리
- business logic : 비지니스 개념, 규칙, 흐름제어
- data access : 데이터 처리
- 레이어드 아키텍처의 규칙:
- 상위 계층이 하위 계층을 호출하는 단방향성을 유지한다.
- 상위 계층은 하위의 여러 계층을 모두 알 필요 없이 바로 및의 근접 계층만 활용한다
- 상위 계층이 하위 계층에 영향을 받지 않게 구성해야 한다.
- 하위 계층은 자신을 사용하는 상위 계층을 알지 못하게 구성해야 한다.
- 계층 간의 호출은 인터페이스를 통해 호출하는 것이 바람직하다(구현 클래스에 직접 의존하지 않음으로써 약한 결합을 유지해야 한다.)
- 일반적인 레이어드 아키텍처에서는 OCP(Open-Closed Principle)이 위배된다.:
- 이는 모든 계층이 각기 자신이 제공하는 기능에 대한 추상적인 인터페이스를 직접 정의하고 소유하고 있는 구조이기 떄문이다.
- 이런 구조에서는 제어 흐름(flow of control)이 상위 계층에서 하위 계층으로 흐르게 되고, 이에 딸느 소스코드의 의존성은 제어 흐름의 방향대로 따를 수 밖에 없다.
- 데이터 액세스 인퍼에스의 위치가 하위 계층이기 때문에 상위 계층이 하위 계층에 의존하게 된다. 따라서 DIP(Dependency-Inversion Principle)을 적용할 필요가 있다.
- 헥사고날 아키텍쳐:
- 레이어드 아키텍쳐에서 DIP를 적용해도 한계가 있으며, 현대 애플리케이션에서는 다양한 인터페이스를 필요로 한다.
- 인바운드 어댑터(inbound adapter) : 외부 영역에서 들어오는 요청을 처리하는 포트
- 아웃바운드 어댑터(outbound adapter) : 비지니스 로직에 의해 호출되어 외부와 연계되는 아웃바운드 어댑터
- 클린 아키텍처:
- 프레임워크 & 디바이스 (외부 인터페이스, 디바이스, 웹)
- 인터페이스 어댑터(프리젠터, 게이트웨이, 컨트롤러)
- 어플리케이션 업무 규칙(유스케이스)
- 비지니스 업무 규칙(엔티티)
3.3 마이크로서비스의 내부 구조 정의
- 바람직한 마이크로서비스의 내부 아키텍처: 클린 마이크로서비스:
- 지향하는 관심사에 따라 응집성을 높이고 관심사가 다른 영역과의 의존도를 낮추게 해야한다.
- 업무 규칙을 정의하는 비지니스 로직 영역을 다른 기술 기반 영역으로부터 분리하기 위해 노력한다.
- 세부 기술 중심 저수준의 외부 영역과 핵심 업무 규칙이 정의도니 고수준의 내부 영역으로 구분한다.
- 고수준 영역은 저수준 영역에 의존하지 않게 해야하며, 저수준 영역이 고수준 영역에 의존해야 한다.
- 저수준 영역은 언제든지 교체, 확장 가능해야 하며, 이 같은 변화가 고수준 영역에 영향을 줘서는 안된다.
- 자바처럼 인터페이스 및 추상 클래스를 지원하는 언어의 경우 저수준 영역의 구체 클레스가 고수준 영역의 추상 인터페이스에 의존하게 하는 의존성 역전의 원칙을 적용한다.
- 인터페이스는 고수준의 안정된 영역에 존재해야 하며, 저수준의 어댑터가 이를 구현한다.
- 내부영역 - 업무 규칙:
- 서비스 인터페이스, 서비스 구현체, 도메인, 리포지토리 인터페이스, 도메인 이벤트 인터페이스, API 프락시 인터페이스가 존재한다.
- 트랜잭션 스크립트 패턴:
- 도메인 객체가 행위를 가지고 있지 않다.
- 모든 비지니스 책임은 서비스에 있다.
- 도메인 모델 패턴:
- 도메인 객체가 데이터 뿐만 아니라 비지니스 행위를 가지고 있으며 데이터는 도메인 객체가 제공하는 행위에 의해 은닉된다.
- 잘 정의된 도메인 모델은 코드의 양을 줄이고 재사용성도 높인다.
- 도메인 주도 설계의 애그리거트 패턴:
- 애그리거트 루트만 참조한다.
- 애그리거트 내 상세 클래스를 바로 참조하지 않고 루트를 통해 참조해야 한다. 수정할 때도 마찬가지다.
- 애그리거트 간의 참조는 객체를 직접 참조하는 대신 기본 키를 사용한다.
- 기본 키를 사용하면 느슨하게 연관되고 수정이 필요하지 않은 애그리거트를 함께 수정하는 실수를 방지하게 한다.
- 하나의 트랜잭션으로 하나의 애그리거트만 생성 및 수정한다.
- 외부 영역- 세부사항:
- API 퍼블리싱 어댑터:
- REST API 를 발행하는 인바운드 어댑터
- API 프록시 어댑터:
- 다른 서비스의 API를 호출하는 아웃바운드 어댑터
- 저장소 처리 어댑터:
- OR 매핑방식 -> 도메인 모델 패턴을 사용할 경우 주로 선택
- SQL 매핑방식 -> 트랜잭션 스크립트 패턴을 사용할 경우 주로 선택
- API 퍼블리싱 어댑터:
- 도메인 이벤트 발행 어댑터:
- 애그리거트 패턴을 적용할 경우 이벤트는 애그리거트에서 발생한 사건
- 도메인 이벤트가 생성되는 위치는 내부영역
- 도메인 이벤트 핸들러
3.4 정리
- 국내 현장에서 광범위하게 사용되고 있는 데이터베이스 중심 아키텍처는 모든 성능 측면을 데이터베이스에 의존시킴으로써 문제가 있으며, MSA의 장점을 퇴색시킬 수 있다.
- MSA 외부 아키텍처뿐만 아니라 서비스 내부 구조도 유연하게 구조화하는 것이 필요하며 유연성과 확장성을 지원하는 대표적인 어플리케이션 아키텍처로 레이어드 아키텍처, 헥사고날 아키텍처, 클린 아키텍처가 있다.
- 일반적인 레이어드 아키텍처의 적용은 한계가 있으며, 의존성 역전의 원칙을 활용해 레이어드 아키텍처를 개선할 수 있다.
- 헥사고날 아키텍처를 활용한 마이크로서비스 아키텍처의 내부 구조에서는 외부 영역이 내부 영역에 의존하도록 구성하는 것이 바람직한다.
- 마이크로서비스의 내부 영역을 정의할 때 비지니스가 단순한 경우에는 트랜잭션 스크립트 패턴을 활용하고, 비지니스가 복잡한 경우에는 트랜잭션스크립트 패턴보다는 도메인 모델 패턴을 적용하는 것이 바람직하다.
4 마이크로서비스와 애자일 개발 프로세스
- 애자일 방법론의 대표 : 스크럼과 XP
- 애자일이 국내에 유입되는 과정에서 왜곡이 발생했고 오해가 있다.
- 애자일에서는 빨리, 그리고 자주 실패를 경험해보는 것이 중요하다.
4.1 도메인 주도 설계와 마이크로서비스
- DDD(Domain Driven Development, 도메인 주도 설계):
- 도메인 중심의 마이크로서비스를 도출하는 지침 및 마이크로서비스 내부의 비지니스 로직 설계의 주요한 가이드로 사용되고 있다.
- 전략적 설계(strategic design) : 도메인 전문가 및 기술팀이 함께 모여 유비쿼터스 언어(uniquitous langauage)를 통해 도메인 지식을 공유 및 이해하고 이를 기준으로 개념과 경계를 식별해 바운디드 컨텍스트(bounded context)fㅗ 정의하고 경계의 관계를 컨텍스트 맵(context map)으로 정의하는 활동
- 전술적 설계(tactical design) : 식별된 바운디드 컨텍스트 내의 도메인 개념인 도메인 모델을 구성하는 유용한 모델링 구성요소들을 설명한다.
4.2 기민한 설계/개발 프로세스
- 점진/반복적인 스크럼 생명주기:
- 스크럼팀: 스프린트가 진행되는 팀을 스크럼 팀이라고 한다. 스크럼 팀은 스크럼 마스터와 팀 맴버로 구성된다. 스크럼 팀은 앞에서 언급한 다기능 팀으로서 프런트엔드 개발자, 백엔드 개발자, 설계자, 테스터, 비지니스 전문가, 디자이너 등이 한팀을 구성한다. 여러 직능을 가진 전문가들이 같은 팀에 모여 있으므로 의사결정이 빠르고 협업이 긴밀하다. 스크럼 마스터는 협업을 촉진하고 팀의 장애물을 제거하는 역할을 수행한다.
- 스크럼 미팅: 스크럼 팀은 매일 아침 각자의 자리에 서서 짧게 진행되는 스탠드업 미팅을 통해 각자의 일을 투명하게 공유한다.
- 스프린트 계획 수립: 시스템의 모든 요구사항은 제품 백로그에 담긴다. 그다음 일정에 맞게 스프린트를 몇번 수행할 것인가가 결정된다. 보통 스프린트는 1~4주의 기간이다. 스프린트 횟수가 결정되면 제품 백로그에 담긴 백로그를 각 스프린트에 적절히 배분한다. 스프린트가 종료되면 백로그 완료 일감을 기준으로 팀의 생산성이 결정된다. 이를 속도라고 부룬다.
- 시연 : 스프린트 마지막의 활동은 시연과 회고다. 시연은 초기에 정의한 백로그가 모두 구현되고 그 요건을 만족하는지 확인하는 자리다. 이때 피드백을 받을 수 있고 다음 스프린트에 반영할 요건들을 확인할 수 있다.
- 회고 : 회고는 팀원들이 자기 스스로를 돌아보는 과정이다. 마이크로서비스를 설계 및 개발하는 과정에서 좋았던 방식과 안 좋았던 방식을 논의하고 개선점을 찾아 다음 스프린트에 적용할 수 있다.
- 아키텍처 정의와 마이크로서비스 도출:
- 아키텍처 정의: 마이크로서비스 외부/내부 아키텍처를 정의하는 공정. 최소한의 개발 및 테스트 환경을 먼저 준비하는 것이 효율적이다.
- 마이크로서비스 도출: 본격적인 마이크로서비스 개발로 들어가기 위한 스크럼 팀이 개발할 전체 마이크로서비스들을 파악하는 작업
- 스르핀트 내 개발 공정:
- 백엔드 설계 및 개발:
- API 설계
- 도메인 모델과 데이터 모델 설계
- 프런트엔드 영역 설계와 개발:
- UI 흐름 정의: 비지니스 흐름에 따른 UI 흐름을 정의한다. UI 흐름을 설계한 산출물을 UI 스토리보드라고도 한다.
- UI 레이아웃 정의: 사용자 접점인 사용자 인터페이스를 정의하는 활동이다. 디자인을 고려하지 않은 사용자 경험을 고려해서 설계한다. 최근에는 발사믹 목업이나 카카오 오븐 등의 도구가 많이 사용된다.
- UI 이벤트 및 액션 정의: UI 레이아웃의 구성요소인 컨트롤을 클릭하거나 터치 드으이 행위를 했을 때 발생하는 이벤트 및 액션을 정의하는 활동.
- UI 개발: UI 레이아웃 및 이벤트의 의도에 맞춰 프런트엔드 애플리케이션을 개발하는 활동이다. 보통 프런트엔드 아키텍처에서 정의한 UI 프레임워크나 도구를 사용할 수 있다.
- 빌드 및 배포:
- 소스코드 리포지토리 구성: 프런트엔드, 벡엔드 코드를 위한 소스코드 리포지토리를 구성한다. 이때 SVN, Git 등이 활용된다.
- 통합 빌드 잡(Build Job) 구성 : 리포지토리에 존재하는 소스코드를 통합한 후 컴파일 및 테스트해서 바이너리를 만드는 활동을 자동화 한다.
- 컨테이너 생성파일 작성 : 배포 환경을 컨테이너 환경으로 구성할 경우 운영체제와 WAS와 빌드된 애플리케이션을 묶어서 컨테이너 이미지를 생성하는 스크립트를 작성할 수 있다.
- 배포 스크립트 작성: 자동으로 배포하는 스크립트를 작성하는 활동
- 백엔드 설계 및 개발:
4.3 정리
- 스프린트 계획 수립, 시연/회고, 스크럼 미팅
- 아키텍처 정의, 마이크로서비스 도출, 벡엔드/프런트엔드 설계 및 개발, 빌드/배포의 설계와 개발 공정
5 마이크로서비스 설계
- high cohension, low coupling
5.1 마이크로서비스를 도출하는 방법
- 비지니스 능력에 근거한 도출
- DDD의 바운디드 컨텍스트 기반 도출
5.2 DDD에서의 설계
- 바운디컨텍스트 : 비지니스 응집성이 있는 컨텍스트, 분리된 도메인 모델에 의해 다른 컨텍스트와 구별되는 경계
5.3 DDD의 전략적 설계
- 도메인과 서브도메인:
- 핵심 서브도메인 : 다른 경쟁자와 차별화를 만들 비지니스 영역
- 지원 서브도메인 : 비지니스에 필수적이지만 핵심은 아닌 부분
- 일반 서브도메인 : 비지니스적으로 특화된 부분은 아니지만 전체 비지니스 솔루션에는 필요한 부분
- 유비쿼터스 언어와 도메인 모델, 바운디드 컨텍스트:
- 유비쿼터스 언어: 특정 도메인에서 해당 도메인에서의 의도를 명확히 반영하고 도메인의 핵심 개념을 잘 전달할 수 있는 언어
- 도메인 모델 : 특정 비지니스 맥락에서 통용되는 개념들의 관계를 잘 정의한 모형
- 컨텍스트 매핑:
- 바운디드 컨텍스트를 식별할 때 각 컨텍스트는 내부적으로는 응집성이 높고, 다른 컨텍스트와는 의존관계가 낮아야 한다는 원칙하에 설계
- 주요한 컨텍스트 매핑 관계:
- 공유 커널(Shared Kernel) : 바운디드 컨텍스트 사이에 공통적인 모델을 공유하는 관계다.
- 소비자와 공급자(Customer-Supplier) : 데이터의 흐름이 상류에서 하류로 흐르는 관계, 공급자가 소비자에 맞춰서 원하는 기능을 제공
- 준수자(Confirmist) :소비자와 공급자와 유사하지만 상류 팀이 하류팀의 요구를 지원하지 않거나 못하는 경우에 사용. 이런 경우에는 하류팀은 상류팀에서 제공하는 모델을 그대로 사용
- 충돌 방지 계측(ACL; Anit-Corruption Layer): 하류 팀이 상류팀의 모델에 영향을 받을 때 하류 팀의 고유 모델을 지키기 위해 번역 계층을 만드는 것.(디자인 설계에서 어댑터 패턴 생각하면 됨)
- 공개 호스트 서비스(OHS; Open Host Service): 바운디드 컨텍스트에 대한 접근을 제공하는 프로토콜이나 인터페이스를 정의하는 것. 이 프로코톡은 하류으 ㅣ컨텍스트가 상위 컨텍스트에서 제공하는 기능을 용이하게 사용할 수 있도록 공개돼 있다.
- 발행된 언어(PL; Published Language): 하류의 컨텍스트가 상류의 컨텍스트가 제공하는 기능을 사용하기 위한 간단한 사용과 번역을 가능케 하는 문서화된 정보 교환 언어(XML, JSON 등), 주로 공개 호스트 서비스와 짝을 이뤄 사용한다.
- 컨텍스트맵: 하나의 큰 도메인을 여러 개의 바운디드 컨텍스트로 식별하고 이들 간의 관계를 표현한 그림
5.4 이벤트 스토밍을 통한 마이크로서비스 도출
- 이벤트 스토밍 : 이벤트 중심으로 이해관계자들이 모여 브레인 스토밍하는 워크숍
- 공간 : 깨끗한 벽 또는 큰 탁자가 있는 넓은 공간
- 참가자 : 고객, 도메인 전문가, 설계자, 개발자, 테스트 등 모든 이해 관계자
- 준비물 : A0 전지, 펜과 스티커 등
- 열린 분위기로 활동을 촉진하고 리딩할 수 있는 퍼실리테이터(facilitator)
-
일반적으로 사용하는 스티커 유형별 의미: | 유형 | 크기/색깔 | 설명 | |——————-|———————|——————————————————————| | 도메인 이벤트 | 오렌지색(orange) | 발생한 사건, 과거시제동사로 표현 | | 커맨드 | 파란색(blue) | 도메인 이벤트를 트리거하는 명령 | | 외부 시스템 | 핑크색(pink) | 도메인 이벤트가 호출하거나 관계가 있는 레거시 또는 외부 시스템 | | 액터 | 작은 노란색(yellow) | 개인 또는 조직의 역할 | | 애그리거트 | 노란색(yellow) | 도메인 이벤트와 커맨드가 처리하는 데이터, 상태가 변경되는 데이터 | | 정책 | 라일락 색(lilac) | 이벤트 조건에 따라 진행되는 결정, When [이벤트] Then [커멘드] | | 읽기 모델 | 초록색(green) | 도메인 이벤트 액터에게 제공되는 데이터 | | 사용자 인터페이스 | 흰색(white) | 스케치 형태의 화면 레이아웃 | | 핫스팟(hotspot) | 자주색(purple) | 의문, 질문, 미결정 사항 |
- 이벤트 스토밍 워크숍 진행 순서:
- 도메인 이벤트 찾기
- 외부 시스템/외부 프로세스 찾기
- 커맨드 찾기
- 핫스폿 찾기
- 액터(사용자/역할) 찾기
- 애그리거트 정의하기
- 바운디드 컨텍스트 정의하기
- 컨텍스트 매핑하기
- 최종적으로 마이크로서비스를 정의하기 위해서 하는 질문:
- (비지니스 측면) 비지니스 프로세스를 수행하기 위한 하나의 맥락의 단위로 구분될 수 있는가?
- (데이터 관점) 마이크로서비스별로 분리된 데이터를 정의할 수 있는가?
- (운영 조직 측면) 하나의 팀이 독맂벅으로 운영 가능한 단위인가?
- (배포 측면) 독립적으로 배포 가능한 단위인가?
- (변경 영향도) 변경 시 영향을 받는 마이크로서비스가 존재하는가?
- (클라우드/MSA 도입 목적 측면) 도입을 통한 기대효과를 충분히 활용할 수 있는가?
5.5 마이크로서비스 상세설계
- 프런트엔트 모델링:
- 프런트 아키텍쳐 정의
- 표준 레이아웃 정의
- UI 레이아웃 설계
- UI 디자인 및 UI레이아웃 반영
- 이벤트 설계
- 벡엔드 모델링:
- API 설계:
- REST API 성숙도:
- 레벨 0: REST API의 매커니즘을 전혀 사용하지 않고 전통적인 원격 프로시저 호출 방식으로 HTTP 프로토콜만 사용한 것
- 레벨 1: URI에 개별적인 자원을 표현하는 것
- 레벨 2: 서비스의 기능을 처리하기 위해 약속된 HTTP 메서드들을 사용하는 것
- 레벨 3: HATEOAS(Hypertext As The Engine Of Application State)
- REST API 성숙도:
- API 설계:
5.6 도메인 모델링
- 단순한 로직인 경우에는 트랜잭션 스크립트 구조로 만들어도 되지만, 비지니스가 복잡해질수록 도메인 모델 구조가 효과적이다.
- DDD의 전술적 설계(도메인 모델링 구성요소):
- 엔티티
- 값 객체
- 표준 타입
- 애그리거트
- 도메인 서비스
- 도메인 이벤트
5.7 정리
- 이벤트스토밍
6. 사례 연구 - 마이크로서비스 도출과 아키텍처 구성
6.1 요구사항 정의
6.2 이벤트 스토밍을 통한 마이크로서비스 도출
- 왼쪽에서 오른쪽 방향으로 업무 처리 흐름별로 도메인 이벤트(오렌지색)를 모두 붙인다.
- 다음으로 이벤트와 대응되는 커맨드(파란색)를 도출해서 이벤트 오른쪽에 붙인다.
- 액터(작은 노란색)를 통해 도출될 이벤트와 커맨드를 검증하며 커맨드 왼쪽 아래에 붙인다.
- 이벤트와 연관된 외부 인터페이스(핑크색)를 식별한다.
- 그 다음에는 각 이벤트와 커맨드에 영향을 받는 데이터 요소인 애그리거트(노란색)를 찾는다.
- 마지막에는 이벤트 발생 시 타 영역의 커맨드를 트리거하는 정책(라이락색)을 도출한다.
6.2.2 바운디드 컨테스트 식별
- 서브 도메인 : 사각형
- 바운디드 컨텍스트 : 타원형
- 동기, 비동기 : 실선, 점선
6.2.3 컨텍스트 다이어그램
- 컨텍스트 매핑 다이어그램
6.2.4 이벤트 스토밍 결과를 헥사고날 아키텍처로 표현하기
| 이벤트 스토밍 | 헥사고날 아키텍처 구성요소 | | - | - | | 커맨드 | 외부 영역의 인바운드 어댑터 - API 후보 | | 이벤트 | 외부 영역의 아웃바운드 어댑터로 전송되는 메시지 이벤트 후보 | | 애그리거트 | 내부 영역의 도메인 모델의 후보 | | 인터페이스 | 외부 영역의 아웃바운드 어댑터로 연결될 대외 인터페이스 후보 | | 정책 | 내부영역의 비지니스 로직 구현 규칙, 외부 영역의 아웃바운드 어댑터로 연결될 다른 서비스와의 방향을 결정하는데 도움이 됨 |
6.3 외부 아키텍처 정의
- 백엔드 마이크로서비스
- 프론트엔드
- API 게이트웨이 : Road Balancing, Routing
- 서비스 저장소 : RDB, NoSQL
- 서비스 통신 : 동기 통신(REST), 비동기 통신(메시지 큐)
- 메시지 큐 : Kafka, RabbitMQ
- 배포 : Docker, k8s
- 로그 중앙화 : ELK(Elastic search + Logstash + Kibana)
- 모니터링 : 키알리(Kiali)로 모니터링 및 트레이싱을 수행한다.
- 형상관리 : git
- 개발 환경 구축 : JHipster
6.4 내부 아키텍처 정의
6.4.1 패키지 구조 및 명명 규칙
-
도메인 모델 중심의 마이크로서비스 패키지 명명 규칙 | 구분 | 패키지명 | 유형 | 명명 규칙 | 명칭 및 역할 | 작성 기능 | | - | - | - | - | - | - | | 내부 영역 | domain | 클래스 | 도메인 개념을 명확히 표현할 수 있는 명사형 | 도메인 모델: 비지니스 개념 및 로직 표현 (애그리거트, 엔티티, VO, 표준 타입 패턴으로 구현) | 애그리거트 단위 | | 내부 영역 | service | 인터페이스 | ~Service | 서비스 인터페이스: 서비스 퍼사드 역할 | 애그리거트당 1개 | | 내부 영역 | service | 클레스 | ~ServiceImpl | 서비스 구현체: 업무 처리 흐름 구현 | 서비스 인터페이스당 1개 | | 내부 영역 | respoitory | 인터페이스 | ~Repository | 리포지토리: 저장소 처리 | 엔티티당 1개 | | 외부 영역 | web.rest | 클래스 | ~Resource | REST 컨트롤러: REST API 발행, 인바운드 요청 처리 | | | 외부 영역 | adaptor | 클래스 | ~Client | REST 클라이언트: 동기 아웃바운드 처리, 다른 서비스를 동기 방식으로 호출 | 호출할 타 서비스당 1개 | | 외부 영역 | adaptor | 클래스 | ~Consumer | 컨슈머 어댑터: 비동기 메시지 인바운드 수신처리 | | | 외부 영역 | adaptor | 인터페이스 | ~Producer | 비동기 메시지 인터페이스 : 비동기 아웃바운드 메시지 전송을 정의하는 인터페이스 | 호출할 타 서비스당 1개 | | 외부 영역 | adaptor | 클래스 | ~ProducerImpl | 비동기 메시지 구현체: 비동기 아웃바운드 메시지 전송을 구현 | Producer에 의존 | | 외부 영역 | dto | 클래스 | ~DTO | 데이터 전송 객체: 동기 호출 시 데이터 전송 객체로 사용 | API에 의존 |
-
트랜잭션 스크립트 패턴의 마이크로서비스 패키지 명명 규칙 | 구분 | 패키지명 | 유형 | 명명 규칙 | 명칭 및 역할 | 작성 기능 | | - | - | - | - | - | - | | 내부 영역 | domain | 클래스 | 명사형 | 마이바티스 쿼리로 매핑되는 데이터 묶음(Holder) | 테이블 엔티티 단위 | | 내부 영역 | service | 인터페이스 | ~Service | 서비스 인터페이스: 서비스 퍼사드 역할 | 서비스 인터페이스는 특정 업무의 CRUD를 묶어 표현한다. | | 내부 영역 | service | 클레스 | ~ServiceImpl | 서비스 구현체: 업무 처리 흐름 구현 | 서비스 인터페이스당 1개 | | 내부 영역 | respoitory | 인터페이스 | ~Mapper | 리포지토리: 저장소 처리 | 도메인 패키지의 데이터 묶음당 1개 | | 외부 영역 | web.rest | 클래스 | ~Resource | REST 컨트롤러: REST API 발행, 인바운드 요청 처리 | 서비스 인터페이스당 1개 | | 외부 영역 | adaptor | 클래스 | ~Client | REST 클라이언트: 동기 아웃바운드 처리, 다른 서비스를 동기 방식으로 호출 | 호출할 타 서비스당 1개 | | 외부 영역 | adaptor | 클래스 | ~Consumer | 컨슈머 어댑터: 비동기 메시지 인바운드 수신처리 | | | 외부 영역 | adaptor | 인터페이스 | ~Producer | 비동기 메시지 인터페이스 : 비동기 아웃바운드 메시지 전송을 정의하는 인터페이스 | 호출할 타 서비스당 1개 | | 외부 영역 | adaptor | 클래스 | ~ProducerImpl | 비동기 메시지 구현체: 비동기 아웃바운드 메시지 전송을 구현 | Producer에 의존 | | 외부 영역 | dto | 클래스 | ~DTO | 데이터 전송 객체: 동기 호출 시 데이터 전송 객체로 사용 | API에 의존 | | 외부 영역 | mybatis-mapper | XML 파일 | ~Mapper.xml | SQL 구문 작성 | 레포지토리당 1개 |
6.5 JHipster를 활용한 아키텍처 구성
- JHipster의 목적:
- 광범위한 테스트를 커버할 수 있는 우수한 성능의 강력한 서버 스택
- 세련되고 현대적인 모바일 친화적 UI를 Angular, React, Vue + Bootstrap
- Webpack 및 Maven 또는 Gradle을 사용해 애플리케이션을 빌드하는 강력한 워크플로
- 클라우드에 빠르게 배포할 수 있는 코드 기반 인프라
JHipster로 개발 시작하기
- 게이트웨이 생성
- 레지스트리 생성
- 마이크로서비스 생성
- 생성한 마이크로서비스에 엔티티 생성
- 생성된 엔티티를 게이트웨이가 인식할 수 있도록 게이트웨이에 등록
7 사례연구 - 백엔드 마이크로서비스 구현
| API 명 | 도서 대출 |
| 리소스 URI | /retnals/{userid}/rentedItem/{book} |
| 메서드 | POST |
| 요청 매개변수 | 사용자 인련번호, 도서 일련번호 |
| 요청 예시 | http://localhost:8080/rentals/5/rentedItem/10001 |
| 응답 결과 | 정상 처리 시 도서대출정보를 반환 - Rental 일련번호, 사용자 일련번호, 대출 가능 여부, 연체료 |
| 응답 예시 | {"id": 1, "userId": 5, "retalStatus": "RENT_AVAILABLE", "lateFee": 0}
|