Home 마이크로서비스 아키텍처 이해하기
Post
Cancel

마이크로서비스 아키텍처 이해하기

Overview

이번 글에서는 MSA가 무엇인지를 이해하고, 특징이 무엇인지, 어떤 활용 가치를 가지는 지에 대해서 이야기 해보겠습니다.

MSA를 이해하기에 앞서서 MSA가 등장하고 주목받게된 이유에 대해서 설명하기 위해 기존에 사용되던 형태인 Monolithic Architecture에 대해서 살펴보겠습니다.

Monolithic Architecture

Monolithic-architecture.png

Monolithic Architecture는 어플리케이션을 구성하는 서비스(기능)들이 하나의 유닛으로 개발/배포/운영되는 형태입니다.

온라인 쇼핑몰 어플리케이션을 예를 들면 주문,계정관리,상품관리 등의 모든 기능을 하나의 Spring 앱으로 개발/배포/운영되는 것입니다. (*Spring 앱 내에서 MVC로 설계하고 기능을 나누어 개발하였더라도 이는 하나의 앱으로 배포되기 때문에 Monolithic Architecture에 포함됩니다.)

이러한 방식은 작은 규모의 어플리케이션을 개발하고 운영할 때에 효율적일 수 있으나 규모가 커짐에 따라 여러 문제점들이 발생합니다.

  • 라이브러리 의존성

    각 서비스에서 필요한 라이브러리의 버전 충돌이 발생할 수 있습니다.

    예를 들면 주문 기능은 XX Library 1.1 버전을 사용하여 개발되었는 데, 상품관리 기능은 XX Library 3.3 버전을 사용하여 개발되었다면 서로 필요한 버전이 다르게 됩니다. 이러한 경우 의존성 문제가 발생하여 어플리케이션을 정상적으로 실행시키지 못할 수 있습니다.

  • 비효율적인 확장

    특정 서비스만 사용량이 늘어 확장이 필요한 경우에도 전체 어플리케이션을 확장해야합니다. 이는 수평적 확장이 이뤄질 때 서버에 불필요한 리소스를 잡아먹을 뿐만 아니라, 어플리케이션이 프로비저닝되는 시간이 증가하는 문제도 발생합니다.

    예를 들면 주문이 폭주하였을 때 주문 서비스만 확장하는 것이 아닌 전체 쇼핑몰 어플리케이션을 확장해야합니다.

  • 비효율적인 테스트/배포

    특정 서비스만 수정하더라도 전체 어플리케이션을 테스트하고 배포해야합니다. 이로 인해 전체적인 개발 프로세스 주기가 느려질 수 있습니다.

  • 장애 전파

    특정 서비스(기능)에 장애가 발생할 때 다른 서비스에 전파될 수 있습니다.

    장애 전파를 최소화 하기 위해서 개발자가 전체 어플리케이션의 구조와 서비스 간 연관관계를 이해해야 하며 이는 비효율적인 개발로 이어질 가능성이 높습니다.

  • 조직 문화

    규모가 큰 어플리케이션을 하나로 관리하게 되면 조직 관리를 위해 역할에 따라 부서가 구분되게 됩니다. (프론트엔드 개발 부서, 백엔드 개발 부서, DBA 부서)

    다른 부서와 소통하는 것은 생각보다 쉽지 않으며 공식적인 절차를 거쳐야 합니다. 이는 서로 다른 이해관계, 책임 분산 등으로 인해 부서 간의 의견 충돌, 책임 전가, 느린 피드백 등의 문제를 일으킬 수 있습니다. 그리고 이는 의사결정 및 개발의 지연을 일으키는 좋지 못한 조직 문화를 형성하게 됩니다.

점차 커지는 규모의 어플리케이션에서 이러한 문제점들을 극복하기 위해서 MSA(Microservice Architecture)가 등장하게 되었고 여러 장점들로 인해 관심을 받게 됩니다.

Microservice Architecture (MSA)

Microservice-architecture.png

MSA는 어플리케이션을 구성하는 서비스(기능)들을 각각의 유닛으로 개발/배포/운영되는 형태입니다.

온라인 쇼핑몰 어플리케이션을 예를 들면 주문 기능을 xx앱으로, 계정관리 기능을 xx앱으로, 상품관리 기능을 xx앱으로 각각 개발/배포/운영되는 것입니다.

이는 큰 규모의 어플리케이션에 발생하는 Monolithic Architecture의 문제점들을 해결할 수 있습니다.

  • 라이브러리 의존성

    각 서비스(기능)은 독립된 시스템에서 실행되기 때문에 라이브러리 버전의 충돌이 발생하지 않습니다.

  • 효율적인 확장

    특정 서비스만 사용량이 늘었다면, 해당 서비스에 대해서만 수평적 확장을 수행할 수 있습니다. 이는 불필요한 서버 리소스를 제거하며, 어플리케이션이 동작을 위해 프로비저닝되는 시간을 줄일 수 있습니다.

  • 효율적인 테스트/배포

    특정 서비스만 수정한다면 특정 서비스에 대해서만 테스트하고 배포하면 됩니다. 이는 전체적인 개발 프로세스 주기를 단축시킬 수 있습니다.

  • 장애 전파 X

    각 서비스(기능)은 독립된 시스템에서 실행되기 때문에 특정 서비스(기능)에 장애가 발생할 때 다른 서비스에 장애가 전파되지 않습니다.

    개발자가 전체 어플리케이션의 구조나 타 서비스의 로직을 이해할 필요가 없습니다. 이는 효율적인 개발로 이어질 수 있습니다.

  • 조직 문화

    어플리케이션을 작은 단위의 서비스별로 개발/배포/운영하게 되면 서비스별로 부서를 구분할 수 있습니다. (주문 서비스 부서에 프론트엔드 개발자, 백엔드 개발자, DBA가 전부 소속됩니다.)

    같은 부서에서 소통하면 공식적인 절차를 거치지 않고 빠르게 피드백을 받을 수 있습니다. 또한, 다른 서비스와 독립되어 있기 때문에 서비스의 장애는 오롯이 부서의 책임입니다. 이는 부서 간 책임 전가와 같은 조직적 문제를 해결하고, 높은 자율성과 책임성을 가지는 조직 문화를 형성할 수 있습니다.

    이는 개발팀과 운영팀이 단일팀으로 병합되어 엔지니어가 개발/테스트/배포/운영까지 작업하는 개념인 devops 를 가능하게 합니다.

    (two-pizza team 이야기를 참조하여 MSA에서 추구하는 조직문화에 대해 이해할 수 있습니다.)

>

여기까지 읽으면 MSA를 Monolithic Architecture의 발전된 형태라고 이해할 수 있지만, MSA도 Monolithic Architecture에 비교되는 단점을 가지고 있습니다.

  • 성능

    프로세스 내부에서 데이터를 주고 받는 것보다 IPC, RPC, HTTP와 같이 서로 다른 프로세스가 데이터를 주고 받는 것이 더 느립니다.

    MSA의 경우 각 서비스가 독립된 시스템에서 실행되기 때문에 서비스 간의 데이터를 주고받을 때 오버헤드가 발생합니다.

  • 복잡성 증가

    MSA를 성공적으로 구현하기 위해 Service Discvoery, Circuit Breaker 등의 기술을 도입해야하고, 그 구조가 복잡해집니다.

결론

각 아키텍처의 장/단점을 명확하게 이해하고 상황에 맞게 적절한 아키텍처를 선택하여 설계하는 것이 중요합니다.

위의 특징과 장/단점을 분석해보았을 때, 내부적으로 빠른 동작이 필요하거나 간단한 어플리케이션의 경우 모놀리식 아키텍처로 설계하는 것이 효율적입니다. (마이크로 서비스 아키텍처로 구현할 경우에 내부 동작의 지연이 발생하거나 관리의 복잡성을 가져올 수 있습니다.)

반대로, 규모가 크고 복잡하거나 지금은 간단하더라도 확장될 가능성이 있는 어플리케이션은 마이크로 서비스 아키텍처로 설계하여 확장성, 개발주기 단축, 이상적인 개발문화 등의 장점을 가져옴으로써 지속적이고 효율적으로 어플리케이션을 개발/테스트/배포/운영할 수 있습니다.

This post is licensed under CC BY 4.0 by the author.

Python - 임시 파일 다루기 (tempfile)

Kubernetes - Healthcheck (liveness-probe, startup-probe, readiness-probe)