본 내용은 2018 AWS Summit SEOUL
강연 중 박선용님의 모놀리스에서 마이크로서비스 아키텍처로의 전환 전략을 보고 정리한 내용입니다.
모놀리식 아키텍처에서 마이크로서비스로 전환시에 어플리케이션에서 중요한 기술이나 패턴들을 분류할 때 무엇을 고려해야 하는지, 패턴 및 분할 전략에 따라 분리한 컴포넌트들을 어떠한 AWS 기술들로 매칭해서 전환할 것인가에 대해 충분히 고민해보고 전략을 수립해야 합니다.
모놀리식이란 각각의 어플리케이션들, 모듈들 간에 강하게 결합 되어있는 구조이지만 마이크로서비스는 모듈간 의존성이 약한 디커플링으로 각 모듈 단위로 배포가 가능하며 빠르게 확장하고 분할하는데 확실한 장점이 있습니다. 비즈니스 요구가 빠르게 변화할수록 마이크로서비스 장점은 더욱 커지게 됩니다. 또한 한 가지 서비스에서 발생하는 장애가 전체 시스템에 영향을 주는 모놀리식과는 다르게 한 가지 모듈의 장애에 전체 시스템이 주는 영향을 최소화할 수 있으며 모듈안에서 장기적 기술 종속을 감소시켜 CI/CD의 장점을 극대화하여 기술에 대한 빠른 적용이 가능해집니다.
마이크로서비스에서 어플리케이션은 각 서비스 단위로 분리되어 있기 때문에 배포 복잡도도 동시에 증가하게 되는데 이를 수작업으로 하나하나 배포를 하는 것은 매우 비효율적이며 운영 인력을 추가로 필요로 하기 때문에 효율적인 배포를 위해 배포의 자동화 도입이 필수적입니다. 하나의 모듈을 구동하기 위해서 필요한 시스템 스택들 또는 메모리에 대한 리소스 소요도 단일로 통합되어 있을 때보다 더 많은 리소스 소요를 필요로 하기 때문에 시스템의 메모리 소요가 상대적으로 높아집니다.
기업의 규모에 따라 마이크로서비스 아키텍처를 보는 시선도 달라지게 되는데 스타트업의 경우 초기부터 마이크로서비스를 적용하는 경우가 드물고 빠르게 성장하는 기능 개발에 모든 시간을 소요하여 리아키텍처링에 대한 필요성이 높으며 이를 당장 해결해야 할 과제라고 생각하지 않고 미래에 언젠가는 해결해야 할 과제라고 인식할 확률이 높습니다. 엔터프라이즈 기업의 경우 대규모 기능이 하나의 어플리케이션에 서로 복잡하게 연계되어 있어 마이크로서비스로의 전환에 많은 공수가 들어가게 됩니다.
그렇다면 어떤 경우에 마이크로서비스 아키텍처로 전환/검토 해야 할까요 ?
쉽고 빠른 어플리케이션의 변경
새로운 개발자의 빠른 적응
새 기술의 빠른 적용
CI/CD의 자동화
위와 같은 요구사항이 있다면 마이크로서비스 아키텍처로의 전환을 검토하고 전환 진행에 앞서 각각의 단위 모듈이 요구하는 퍼포먼스나 요구사항을 패턴별로 명세화합니다. 상태
, 컴퓨팅
, API
, 스토리지
, 보안
, 자동관리
, 확장성
등의 요구사항을 서비스별로 명세화하였다면 AWS 서비스와 매핑하게 됩니다. 아래 보안과 모니터링을 AWS 서비스로 어떻게 매핑하는지에 대한 아키텍처 예시가 있습니다.
마이크로서비스 아키텍처 전환시에는 중요 사항들에는 아래와 같은 것들이 있습니다.
안정적인 아키텍처
- 하나의 서비스는 연계가 강한(Cohesive) 기능들의 집합 (
강한 응집도
)- 동일한 이유로 변경되는 것들은 하나의 서비스일 것 (
SRP
)- 서비스끼리는 느슨한 결합 (
낮은 결합도
)- 각각의 서비스는
테스트 가능한 환경
- 각 서비스는
팀이 개발/관리가 가능할 정도의 규모
소프트웨어 아키텍처의 영향을 주는 것은 품질 속성이지 기능 속성이 아닙니다. 품질 특성은 내부/외부 품질
, 사용 품질
로 다시 분리되며 사용 품질에는 효과성
, 생산성
, 안정성
, 만족도
가 있으며 내부/외부 품질에는 기능적합성
, 신뢰성
, 사용성
, 실행효율성
, 유지보수성
, 이식성
, 호환성
, 보완성
으로 분류되고 각각 하위 속성을 가지고 있습니다.
그렇다면 어플리케이션을 어떤 기준으로 분할할 것인가 ?
- 비즈니스 역량에 의한 분할
- 서브 도메인에 의한 분할
위 두 가지는 방법론으로 제시된 내용이기 때문에 실무에서 고려시 다소 뜬구름 잡는 이야기로 들릴 수도 있습니다. 여기서 비즈니스 역량이란 비즈니스 목적과 동일합니다. 비즈니스의 가치 창출의 요소를 기준으로 분할하는 것입니다. 비즈니스 역량을 구분하여 각 비즈니스 역량에 포함되는 서비스로 전환하는 것입니다.
서브 도메인에 의한 구분으로 볼 때 도메인 주도 디자인(DDD: Domain Driven Design)
의 방법론을 통한 구분으로 개념서로는 훌륭한 방법이지만 핵심을 구분하기 쉽지 않습니다. 서브 도메인을 특정하는 것이 어려우며 각기 다른 그룹이 서브도메인과 관련될 수 있기 때문입니다. 즉 핵심(Core)
은 자사에서 구축하고 일반(Generic)
에 포함되는 것은 서드파티 툴을 사용하거나 지원(Supporting)
에 포함되는 것은 아웃소싱을 하는 것입니다. 그렇다면 핵심을 구분하는 것이 왜 어려운 것이냐고 한다면 조직구성원 간 핵심을 구분하는 과정에서 조직원별로 각기 다른 기준을 가지고 내린 결론들이 기술적인 판단이라기 보다 정치적인 판단으로 이어지기 쉽기 때문입니다.
따라서 실무적인 접근으로 자사에서 운영하는 서비스의 모든 기능들을 API로 정의하는데 이것을 어떻게 구분할 것인가에 대한 고민과 데이터를 어떻게 분할해야 할 것인가에 대한 고민을 해봐야 합니다. 마이크로서비스에서 한 가지 서비스, 모듈은 자신의 데이터베이스에만 접근할 수 있기 때문입니다. A라는 서비스는 A의 데이터베이스만 접근할 수 있는 것이지 B라는 서비스에서 A의 데이터베이스로 접근할 수는 없습니다. 따라서 데이터를 어떻게 분리해야할 지 먼저 고민해봐야 한다는 것입니다.
크게 서비스 별 데이터베이스 패턴, API 게이트웨이 패턴을 고려해봐야 합니다. 서비스별 데이터 패턴에는 서비스별 테이블, 스키마, 데이터베이스를 고려하고 API 게이트웨이 패턴에는 다양한 어플리케이션에 대한 단일 접근 포인트를 어떻게 제공할 지 고려합니다. 회로 차단기 패턴(Circuit Breaker)패턴
을 예로 들면 이는 클라이언트가 전기 회로 차단기와 비슷한 방식으로 기능하는 프록시를 통해 원격 서비스를 호출하는 패턴입니다. 하나의 중요한 서비스가 장애를 발생시키면 회로 차단기와 비슷하게 기준점을 통과하지 못할 경우 해당 서비스를 차단하여 테스트에 들어가며 기준점에 도달할 경우 다시 서비스에 연결하여 장애를 일으키는 서비스가 리소스를 점유하는 것을 방지합니다.
데이터 분할 방법은 외래키 관계 제거
, 공유 데이터
, 스키마 분리
, 데이터베이스 리팩토링
, 데이터 펌프
, 이벤트 데이터 펌프
등이 있습니다. 여기서 외래키는 데이터 정합성을 유지할 뿐입니다. 데이터베이스의 철학은 데이터를 저장하고 업데이트하고 단순하게 읽어오는 것입니다. 관계형 데이터베이스 사상이 만들어졌을 때는 메모리 최적화를 위해 중복 데이터를 감소하기 위한 목적으로 테이블을 분리하였지만 데이터베이스 성능이 발전함에 따라 테이블 분리에 너무 집착하여 고려하지 않아도 됩니다.
여러 서비스에서 공유하고 있는 데이터는 공유 서비스로 만들고 스키마를 분리합니다. 스키마를 분리한다는 것은 데이터를 분리하는 것이 아니라 속성(Attribute)을 해당 서비스에 맞게 스키마를 구성하는 것을 말합니다. 스키마 분리가 우선되며 스키마 분리가 성공적으로 진행되었을 때 어플리케이션을 서비스로 분리하는 순서를 가집니다.
분석/리포트 데이터베이스는 API를 통해서 데이터를 리포팅 시스템으로 보내야 하는가 ?
- HTTP를 통한 대량 데이터의 빈번한 전송은 높은 오버헤드가 존재
- 리포팅 시스템 데이터의 동기만을 위한 API는 이득 대비 손실이 크다.
따라서 분석/리포트 데이터베이스는 API로 처리를 하는 것이 아니라 데이터 펌프 또는 이벤트 데이터 펌프를 사용합니다.
데이터 펌프 사용
이벤트 데이터 펌프 사용
이벤트 데이터 펌프를 사용할 경우 이벤트 큐를 앞에 둬서 서비스가 이벤트를 발생시키면 이벤트 구독자(데이터 펌프)가 데이터를 리포팅 데이터베이스로 전달하여 결합도를 낮출 수 있으며 개발에 많은 부담을 감소시킬 수 있습니다.
컴포넌트 별 분할 전략을 수립하여 거시적으로 컴포넌트를 분할한다면 분할된 서비스별로 각각의 요구사항을 가지게 되는데 예를 들어 API를 요청했을때 응답시간 등을 서비스별로 정의합니다. 또한 각 서비스는 자신의 SLA를 충족해야 합니다.
SLA란 ?
SLA(Service-Level Agreement)
는 우리말로서비스 수준 협약
이라고 하며, 고객이 공급업체로부터 기대하는 서비스 수준을 기술한 문서입니다. 해당 서비스의 성과를 측정하는 기준과 합의된 서비스 수준을 달성하지 못할 경우 구제책이나 불이익 등을 함께 명시한 체계적인 계약입니다. 물리적 문서 또는 전자 문서의 형태일 수 있습니다. 서비스 수준 협약의 두 당사자 중 한쪽은 항상 서비스의 고객이고 상대방은 서비스를 제공하는 공급업체가 됩니다. 일반적으로 SLA는 회사의 외부 공급업체 간에 이루어지지만 회사 내 두 부서 간에도 존재할 수 있습니다.
추가적으로 각기 다른 언어를 사용하는 각각의 어플리케이션 서비스를 배포하기 위해서는 컨테이너 기술이 필수적입니다. 마이크로서비스의 컨테이너 기술에 대한 주제로 다음번에 포스팅하겠습니다.
- 기존 어플리테이션에 대해서는 전환계획 수립
- 발견, 패턴, 분할, 매핑 등 단계별 접근 고려
- 각 비즈니스 단위의 구분, 서비스의 요구사항 등 고려
- 데이터 분할에 대한 전략
- 컨테이너 기술 및 서버리스 서비스의 활용
- 각 분할된 서비스 요구사항과 AWS 서비스의 매핑
- 추가적인 표준 AWS 레퍼런스 아키텍처 고려
- 서비스 규모에 따른 지속적인 진화