728x90
마이크로 서비스란?
클라우드 서비스의 발전으로 서버 인프라 구축에 드는 시간이 월등히 감소했고, 이에 맞춰 애플리케이션 개발과 운영도 적시에 진행되도록 하는 설계, 개발, 운영 기법이 요구되었다. 그 중 하나로 떠오른 기법이 바로 마이크로 서비스 기법이다. 이는 독립적으로 개발된 서비스(서비스 컴포넌트)를 여러 개 조합해서 하나의 애플리케이션으로 만드는 구조를 말한다. 이를 통해 소규모 서비스를 빠르게 런칭하고, 철회하는 것이 가능한 유연한 환경을 구성하여 빠른 시장 선점을 기대한다.
장점
작은 단위의 애플리케이션의 릴리즈, 변경이 가능
(기존 모놀리스는 작은 단위의 수정이 곧 애플리케이션 전체 수정을 의미한다.)
각 서비스의 규모, 요청의 정도에 따라 유연한 스케일 인/아웃이 가능하다.
(가령 주문 조회 요청이 높은 트래픽을 발생시킬 경우 해당 서버의 스케일 아웃만으로도 해결이 가능할 수 있으며, 서버가 죽더라도 다른 서비스에 영향을 주지 않는다. 하지만 모놀리스라면 서비스 전체가 블로킹 발생으로 지연되거나 심할 경우 사망할 수 있다.)
단점
분산 컴퓨팅 관리에 따라오는 추가비용 발생
서비스 간 통신 빈도수의 증가로 이는 통신 지연의 가능성이 높아짐을 의미함
DB 간 일관성 유지(동기화)를 위한 비용 발생
시스템 전체에 대한 일관성 유지, 관리 비용이 발생
마이크로 서비스의 특징
마이크로 서비스라 부를 수 있는 요소를 살펴보자
- 서비스 컴포넌트화: 각각의 서비스를 독립적인 팀으로 구성하여 설계, 개발, 운영한다. 이 때 서비스 간의 의존도를 최소화하는 느슨한 결합을 요구한다.
- 비즈니스 기준의 팀 편성: 하나의 서비스 런칭을 위해 해당 도메인 전문가, 디자이너, 소프트웨어 엔지니어, 데브옵스 엔지니어 등이 팀을 이룬다.
- 개발 환경과 영구 데이터 저장의 거버넌스: 각 서비스팀은 독자적으로 운영되어 비중앙집권적 언어와 툴, 데이터를 사용할 수 있다.
- 인프라 환경 구축: 컴파일, 테스트, 배포 등의 자동화(CI/CD)가 권장되며, 장애/오류를 전제하여 로그와 트레이스 기능 구현 및 네트워크 장애 감지 기능 구현이 요구된다.
마이크로 서비스 아키텍처(MSA)의 기본
- 서비스와 DB의 1:1매칭과 로컬 트랜잭션을 권장한다. 각각의 서비스에 대한 데이터는 일관성 유지를 위해 글로벌 트랜잭션이 요구되어야 하는 것 아니냐고 생각할 수 있지만 이는 운영이 복잡해질 뿐만 아니라 MSA의 기본 원칙인 느슨한 결합을 방해한다.
- 데이터 베이스 동기화 수단이 필요하다. 동기화 수단 중 하나로 Saga솔루션이 존재한다. 이는 로컬 트랜잭션, 이벤트 발행, 보상 트랜잭션 등의 기술이 적용된 솔루션이다. 하나의 데이터 저장소에 대한 로컬 트랜잭션이 성공하면 이에 대한 이벤트를 발행하고, 이를 감지한 또 다른 저장소에서 로컬 트랜잭션을 수행한다. 이 과정에서 오류가 발생한다면 이에 대한 실패 이벤트를 역순으로 발행하여 기존에 수행한 로컬 트랜잭션을 취소하도록 하는 보상 트랜잭션을 수행한다.
Saga의 경우 서비스 간 통신이 발생하므로 응답 시간이 길게는 수백 밀리초에서 수 초가 걸릴 수 있다. 그러므로 그 기간 동안에는 일관성이 보장되지 않으며, 만일 오류가 응답될 경우 더 긴 시간 보장되지 않을 수 있다. 그래서 Saga는 한시적으로 일관성이 유지되지 않더라도 결과적으로는 일관성이 유지되는결과 일관성
이 허용되는 서비스에서 적용되어야 한다. 이를 파악하기 위해서는 도메인 전문가의 도움이 필요하지만, 대체적으로 대부분의 상황에서는 결과 일관성 적용이 가능하다고 한다.
- 데이터 결합 전략이 필요하다. 가령 여러 도메인에서 데이터를 취득해 결합해야 하는 경우 API 컴포지션과 CQRS를 대체적으로 고려한다.
API 컴포지션의 경우 애플리케이션 계층에서 각 DB를 통해 필요한 데이터를 확보한 뒤 인메모리 방식으로 조인(JOIN)하는 방식을 말한다. 이는 구현이 단순하다는 장점이 있지만 인메모리라는 점에서 리소스 부족이 발생할 수 있음을 고려해야 한다.
CQRS는 갱신형 처리(삽입/변경/삭제)와 참조형 처리(검색/획득)를 분리된 프로그램과 저장소를 쓰자는 발상에서 비롯되었다. 이는 일반적으로 갱신형 처리가 참조형 처리에 비해 요청수가 낮다는 점을 고려하여 두 처리 방식에 대해 저장소를 따로 관리하도록 요구한다. 구체적으로 갱신형 처리에 대한 데이터는 이벤트 저장소 형태로 저장하도록 하고, 참조형 처리에 대한 데이터는 고속 검색 기능을 가진 데이터 저장소를 사용하도록 한다. 이때 이벤트 저장용 데이터를 잘 설계한다면 여러 DB를 순회할 필요 없이 이벤트를 기반으로 비즈니스 요구사항에 맞는 다양한 검색 데이터 View를 생성하여 검색 저장소에 저장할 수 있다. 하지만 두 저장소는 동기화가 요구되는데 이는 비동기 메시징을 적용하여 비즈니스에 따른 동기화 시점을 설정하여 정기적으로 동기화 되도록 해야한다.
추가적으로 갱신형 처리 저장소를 이벤트 저장소 형태로 취하면 비즈니스 친화적인 데이터 적재하게 된다. 이는 마치 비즈니스 장부를 정리하는, 발생 사건을 로깅하는 효과를 볼 수 있기 때문이다.
- 서비스간 연계를 구현해야 한다. 이는 REST와 메시징이 주로 쓰인다. REST는 일반적으로 쓰던 http 통신으로 이는 동기형 프로토콜에 해당한다. 즉 복잡한 로직이나, 처리 시간이 다소 높은 요청이 대량으로 발생할 경우 응답이 지연되면서 요청이 쌓여 리소스가 고갈될 수 있다.
메시징의 경우 비동기로 이벤트 메시지를 주고 받는 이벤트 발행, 구독 형식을 말한다. 두 서비스 사이에 메시지 브로커를 두어 요청/응답을 동기 또는 비동기형식으로 통신하는 방식이다. 이 중 요청/응답 비동기형식이 확장성에 용이하며 일반적으로 잘 알려진 Kafka와 RabbitMQ가 해당 역할을 한다.
728x90
728x90
'백엔드 개발자(node.js)가 되는 과정' 카테고리의 다른 글
Nestjs 기반 테스트코드 작성법 공부중 - 1일 차 회고 (0) | 2023.12.11 |
---|---|
socket.io를 활용한 채팅 기능 구현에 대한 회고 (2) | 2023.12.08 |
이벤트 기반 아키텍처(EDA) 살펴보기 (2) | 2023.11.21 |
HTTPS와 SSL 인증 방식에 대한 이해 (1) | 2023.10.16 |
AWS Cloudfront의 work flow 살펴보기 (0) | 2023.09.12 |