모놀리식 지옥에서 벗어나라
마이크로 서비스 패턴
모놀리식 지옥에서 벗어나라
모놀리식 아키텍처의 장점
- 개발이 간단하다
- 애플리케이션을 쉽게 변경할 수 있다
- 테스트하기 쉽다
- 배포하기 쉽다
- 확장하기 쉽다
모놀리식 아키텍처의 단점 (커질수록)
- 너무 복잡해서 개발자가 주눅든다
- 개발이 더디다
- 커밋부터 배포까지 길고 험난한 여정
- 확장이 어렵다
- 갈수록 한물간 기술 스택에 발목이 잡힌다
확장 큐브와 마이크로 서비스
- X축 확장 : 다중 인스턴스에 고루 요청 분산
- 모놀리식 애플리케이션의 확장 수단
- 부하분산기 뒷면에 애플리케이션 인스턴스 N개를 띄워 놓고 부하분산기가 인스턴스에 고루 분배하는 방법
- 애플리케이션의 가용성 개선에 좋음
- Z축 확장 : 요청 속성별 라우팅
- 모놀리식 애플리케이션 다중 인스턴스 실행은 동일 하지만 이스턴스 별로 주어진 데이터 하위 집합만 처리
- 예시로 라우터가 요청 헤더 Authorization에 포함된 userId를 보고 N개 동일한 애플리케이션 인스턴스중 선택
- 증가하는 트랜잭션 및 데이터볼륨을 처리하는데 좋음
- Y축 확장 : 기능에 따라 애플리케이션을 서비스로 분해
- 모놀리식 애플리케이션을 여러 서비스로 쪼개는 방법
마이크로서비스 아키텍처의 장점
- 크고 복잡한 애플리케이션을 지속적으로 전달/배포할 수 있다
- 서비스가 작아 관리하기 용이하다
- 서비스를 독집적으로 배포/확장할 수 있다
- 결함 격리가 잘된다
- 신기술을 시험/도입하기 쉽다
마이크로서비스 아키텍처의 단점
- 딱 맞는 서비스를 찾기가 쉽지 않다
- 시스템을 잘못 분해하면 모놀리식과 마이크로서비스의 단점만 있는 분산 모놀리스가 됨
- 분산 시스템은 복잡하다
- 서비스마다 DB가 따로 있기 때문에 다중 DB에 접속하여 조회하고 트랜잭션을 구현하는 일이 어렵다
- 서비스간 사용불능, 지연시간, 부분 실패 서비스 처리를 핸들링해야한다
- 단순 쿼리로 여러 서비스에 있는 데이터를 조회할 수 없음으로 API를 조합하거나, CQRS뷰로 쿼리
- 여러 서비스가 연관된 테스트를 자동화 하는 것이 쉽지 않다
- 종류가 다른 서비스가 여러 인스턴스로 떠 있어 운영 복잡도가 증가된다
- 여러 서비스에 걸친 공통 기능은 배포할 때 잘 살펴야 한다
- 도입 시기를 결정하기 어렵다
마이크로서비스 아키텍처 패턴 언어
- 애플리케이션을 여러 서비스로 분해하는 패턴 2가지
- 비지니스 능력에 따라 서비스를 구성
- DDD하위 도메인에 따라 서비스를 구성
- 통신패턴
- 마이크로서비스 이키텍처로 구축한 애플리케이션은 기본적으로 분산 시스템이기 때문에 프로세스간 통신이 아주 중요하며, 다음과 같은 사항을 고려해야한다.
- 통신 스타일 : 어떤 IPC를 사용하는가 ?
- 디스커버리 : 서비스 클라이언트는 서비스 인스턴스의 IP 주소를 어떻게 가져오는가 ?
- 신뢰성 : 서비스 불능 시 서비스 간 통신의 신뢰성은 어떻게 보장되는가 ?
- 트랜잭셔널 메세징 : 비지니스 데이터를 업데이트하는 DB트랜잭션에 메시지를 송신하고 이벤트 발행하는 행위를 어떻게 통합하는가?
- 외부 API : 애플리케이션 클라이언트는 서비스와 어떻게 통신하는가 ?
- 트랜잭션 관리를 위한 데이터 일관성 패턴
- 서비스 마다 자체 DB 를 가지고 있어 사가 패턴에 따라 서비스 간 데이터 일관성을 유지해야 한다.
- 데이터 쿼리 패턴
- 서비스마다 DB를 두면, 각 서비스가 소유한 데이터를 조인하는 쿼리 처리가 문제인데, 다음 두가지 패턴을 사용할 수 있다.
-
- API 조합패턴 (composition pattern)
- CQRS(Command Query Responsibility Segregation, 커맨드 쿼리 책임 분리)
- 서비스 배포 패턴
- 기존에는 서비스를 언어에 특정한 패키징 포맷으로 묶어 배포
- 요즘은 크게 두가지 방식이 존재
- VM이나 컨테이너에 배포
- 서버리스 -
- 관측성 패턴: 애플리케이션 동작 파악
- 마이크로서비스 아키텍처는 요청 결과가 클라이언트에 반환되기 전가지 어떤 서비스를 어떻게 오갈지 알 수 없기 때문에
로그파일 하나만으로 원인을 파악할 수 없고 문제의 원인을 찾기 어렵다. 관측 가능한 서비스를 설계하려면 다음과 같은 패턴이 필요하다.
- 헬스체크 (health check)
- 로그수집 (log aggregation): 서비스 내역을 기록하고 중앙 로깅 서버에 로그 출력하여 검색/경고 기능 제공
- 분산추적 (distributed tracing) : 각 외부 요청마다 ID를 부여하여 서비스를 통과하는 과정을 추적
- 예외추적 (exception tracking) : 예외가 발생하면 예외 추적 서비스에 보고. 중복된 예외를 걸러내고, 개발자에게 경고를 보내거나 해결상태 추적
- 애플리케이션지표 (application metrics) : 카운터, 게이지등의 지표를 측정하여 지표 서버에 표출
- 검사로깅 (audit logging) : 사용자가 한 일을 기록
- 마이크로서비스 아키텍처는 요청 결과가 클라이언트에 반환되기 전가지 어떤 서비스를 어떻게 오갈지 알 수 없기 때문에
로그파일 하나만으로 원인을 파악할 수 없고 문제의 원인을 찾기 어렵다. 관측 가능한 서비스를 설계하려면 다음과 같은 패턴이 필요하다.
- 서비스 테스트 자동화 패턴
- 컨슈머 주도 계약 테스트 (consumer-driven contract test) : 클라이언트가 의도한 대로 서비스가 동작하는지 확인
- 컨슈머 쪽 계약 테스트 (consumer-side contract test) : 클라이언트와 서비스가 상호 통신 가능한지 확인
- 서비스 컴포넌트 테스트 (service component test) : 서비스를 따로따로 테스트
- 횡단 관심사 처리 패턴
- 신규 서비스 구축 시 횡단(공통) 관심사를 개발하려면 시간이 너무 많이 걸린다. 이 책에서는 새시 패턴을 소개함 (Microservice Chassis)
- 보안 패턴
- 마이크로서비스 아키텍쳐에서는 일반적으로 API게이트웨이가 신원 역할 등 사용자 정보를 인증한 후 호출할 서비스에 정보를 전달한다.
- 일반적으로 JWT(JSON 웹 토큰(Web Token))과 같은 액세스 토큰을 적용