brunch

You can make anything
by writing

C.S.Lewis

by 최준호 Mar 10. 2019

마이크로서비스 아키텍처 (MSA)

기본적인 개념과 우버의 적용 사례 

DZone에 실린 Sahiti Kappagantula의 Microservice Architecture — Learn, Build, and Deploy Applications Get a better understanding of microservice architecture and, as an example of its benefits, how Uber broke down their monolith into microservices. 글을 번역 및 수정한 내용입니다.


바로 들어가기 전에 마이크로서비스 아키텍처(Microservice Architecture)의 정의와 기본 개념에 대한 좀 더 자세한 설명이 필요하면 '리팩토링'의 저자로 유명한 '마틴 파울러가' 정리한 '마이크로서비스'를 꼭 읽어 보시기 바랍니다. (한글로 번역되어 있어 읽기도 편합니다.)


이 글의 주요 내용은 다음과 같습니다:

마이크로서비스 아키텍처 정의

마이크로서비스 아키텍처 주요 개념

마이크로서비스 아키텍처 장단점

우버의 적용 사례

마이크로서비스 아키텍처 정의

마이크로서비스 아키텍처에 대한 정확한 정의를 내리면 좋겠지만 마이크로서비스 및 마이크로서비스 아키텍처에 대한 정확한 정의는 없습니다. 하지만 마이크로서비스란 작고 독립적으로 배포 가능한 각각의 기능을 수행하는 서비스로 구성된 프레임워크라고 할 수 있습니다.

마이크로서비스는 완전히 독립적으로 배포 가능하고 다른 기술 스택(개발언어, 데이터베이스 등)이 사용 가능한 단일 사업 영역에 초점을 둡니다.

그림 1: 모노리틱 이키텍처와 마이크로서비스 아키텍처의 차이점

위 그림에 모노리틱 이키텍처(Monolithic Architecture)와 마이크로서비스 아키텍처의 차이점이 나와 있습니다. 이해를 돕기 위해 마이크로서비스 아키텍처의 몇 가지 주요 개념에 대해 설명하겠습니다.


마이크로서비스 아키텍처 주요 개념

마이크로서비스 아키텍처로 설계하기 전에 애플리케이션의 범위와 기능에 대해 확실히 할 필요가 있습니다.


다음은 마이크로서비스를 설계하기 전 고려해야 할 주요 내용입니다:

개발자가 사업 영역별 기능에 대해 명확히 이해하고 있는가

각각의 서비스가 정말로 오직 하나의 서비스에만 집중하고 있는가

각각의 서비스가 독립적으로 배포 가능한가

각각의 서비스는 스테이트리스 서버(HTTP 웹서버 등)로 통신 가능한가

각각의 서비스는 추후 더 작은 서비스로 리펙토링 가능한가

이러한 마이크로서비스 설계 시 고려할 사항을 숙지했다면, 마이크로서비스의 아키텍처에 대해 알아봅시다.


어떻게 마이크로서비스 아키텍처는 작동하는가?

전형적인 마이크로서비스 아키텍처의 구성요소는 다음과 같습니다:

1. 클라이언트

2. 인증 ID 제공자

3. API 게이트웨이

4. 메시지 포맷

5. 데이터베이스

6. 정적 콘텐츠

7. 서비스 관리

8. 서비스 찾기

그림 2: 마이크로서비스의 구성요소

그림이 좀 복잡하지만 간단히 설명하면 다음과 같습니다:

1. 클라이언트

아키텍처는 다양한 클라이언트에서 시작되는데, 각각의 클라이언트는 조회, 생성, 삭제 등 다양한 수행을 요청합니다. 내부 마이크로서비스도 클라이언트가 될 수 있습니다.

2. 인증 ID 제공자

클라이언트의 다양한 요청은 인증 ID 제공자(Google, Facebook, 자체 ID/PW, Token 등)에 의해 요청에 대한 권한이 있는지 확인됩니다. 권한이 확인되면 요청은 API 게이트웨이로 넘어갑니다.

3. API 게이트웨이

클라이언트는 서비스에 대해 직접 요청할 수 없고, API 게이트웨이가 해당 요청에 대해 적절한 서비스로 전달하는 진입점 역할을 하게 됩니다.
API 게이트웨이를 사용하게 되면 다음과 같은 장점이 있습니다:
- 모든 서비스는 고객이 업데이트로 인한 불편함(업데이트로 인한 서비스 중단, 이전 버전 클라이언트 사용 불가 등)을 격지 않고 배포가 가능합니다.
- 각 서비스 상호 간에는 웹 방식이 아닌 다른 방식으로 통신이 가능하여 성능 향상이 가능합니다.
- 보안이나 로드밸런스 같은 네트워크 외부의 문제를 네트워크 내부의 서비스와 분리시킵니다.
클라이언트로부터 요청을 받으면, 마이크로서비스로 구성된 아키텍처는 상호 간 메시지 통신을 통해 요청을 처리합니다.

4. 메시지 포맷

마이크로서비스가 상호 간 통신할 때 사용하는 메시지는 다음의 2가지 타입이 있습니다:
- 동기 메시지: 주로 클라이언트가 서비스로부터 응답을 기다릴 경우 마이크로서비스는 REST(Representational State Transfer) 방식을 사용해 스테이트리스 HTTP 프로토콜로 응답합니다.
- 비동기 메시지: 클라이언트가 서비스로부터 응답을 기다리지 않을 경우 마이크로서비스는 Queue(AMQP, STOMP, MQTT 등) 방식을 사용하며 주로 내부 서비스 간 통신에 쓰입니다.

5. 데이터베이스

각각의 마이크로서비스는 사업 영역에 맞게 자신만의 데이터베이스를 가지고 있습니다. 또한 각각의 데이터베이스에 다른 서비스가 직접 접근하지 않고, API를 통해 해당 마이크로서비스가 데이터 업데이트 등을 처리하도록 합니다.
그림 3: 마이크로서비스의 데이터 핸들링
마이크로서비스는 다른 서비스 와의 데이터베이스 작업을 위한 API를 제공합니다.

6. 정적 콘텐츠

마이크로서비스가 요청 처리를 끝낸 후 정적 콘텐츠(HTML 페이지 등)를 CDN(Content Delivery Networks)에 배포하거나 기존 클라우드 스토리지에 있는 파일을 직접 접근할 수 있는 링크 정보를 제공합니다.


위의 구성 요소 이외에 일반적인 마이크로서비스에는 다음과 같은 부가 구성 요소가 있습니다.


7. 서비스 관리

이 구성 요소는 서비스 간(혹은 서비스 노드 간) 로드 밸런싱을 하고 인증에 실패할 경우의 처리를 담당합니다.

8. 서비스 찾기

마이크로서비스의 요청 경로와 메시지 통신 전달을 담당합니다.


이제 마이크로서비스의 장단점에 대해 알아보겠습니다.


마이크로서비스 아키텍처의 장단점


우버 적용 사례

우버의 이전 아키텍처

다른 많은 스타트업과 마찬가지로 우버(Uber)도 단일 도시의 단방향 요청을 위한 모노리틱 아키텍처로 만들어졌습니다. 당시에는 하나의 코드베이스(예. git의 프로젝트 레포지토리)로 개발하는 것이 깔끔했고 당시의 주요 비지니스 이슈를 처리하는데 문제가 없었습니다. 하지만 우버는 곧 전 세계에 서비스를 시작했고 확장성과 지속적인 연동 문제에 직면하게 됐습니다.

그림 4: 우버의 모노리틱 아키텍처

REST API가 승객과 운전자를 연결하기 위해 사용됩니다. 

3가지 다른 어댑터(adapter)가 각각 요금청구, 요금지불, 이메일/메지시 전송을 처리하기 위해 API내부에서 사용됩니다.

MySQL 데이터베이스가 모든 데이터를 저장합니다.

따라서 승객관리, 요금청구, 메시지(이메일, 푸시 등), 요금지불, 운행관리 등을 하나의 프레임워크에 구성되어 있습니다


알려진 문제점

우버가 서비스를 세계로 확장하면서 이러한 단일 프레이워크에 많은 난관이 발생했습니다. 다음은 당시 우버가 직면했던 몇 가지 중요한 난제입니다.

하나의 기능을 업데이트하기 위해 모든 기능을 반복적으로 재구성하고 배포하고 테스트해야 한다.

하나의 소스 레포지터리에서 다수의 개발자가 각각 버그 수정하기가 점점 더 힘들어진다.

새로운 기능을 전 세계적으로 동시에 적용하면서 그에 따른 인프라 성능 확장이 매우 힘들다.


문제점 해결

이러한 문제점을 피하기 위해 우버는 아키텍처를 변경하기로 결정했고 고성장을 하고 있는 아마존, 넷플릭스, 트위터와 같은 회사의 사례를 따르기로 했습니다. 그래서, 우버는 기존 모노리틱 아키텍처에서 사용하는 단일 코드베이스 개발에서 다중 코드베이스의 마이크로서비스 아키텍처로 이전하게 됩니다.

그림 5: 우버의 마이크로서비스 아키텍처

가장 큰 변화는 운전자와 승객을 연결하는 API 게이트웨이의 등장입니다. API 게이트웨이로 부터 승객관리, 운전자관리, 운행관리 등 모든 내부 요청이 연결되어 있습니다.

각각의 유닛(서비스)은 독립적으로 분리되어 배포 가능하고 독립적으로 기능을 수행합니다.

예를 들어, 요금청구 서비스에 변화가 있다면 단지 요금 서비스만 수정하여 배포하면 되고 다른 서비스는 배포할 필요가 없습니다.

각각의 기능은 독립적으로 적용 및 확장 가능합니다. 즉, 각각의 기능을 독립적으로 추가하거나 성능 향상할 수 있습니다.

예를 들어, 차량을 찾는 사람이 실제 차량을 예약하고 요금 지불하는 사람보다 현격히 많습니다. 이런 경우 승객관리 서비스의 서버 프로세스의 개수를 요금지불 서비스의 서버 프로세스 개수보다 늘림으로써 성능 향상이 가능합니다.

이런 식으로 우버는 모노리틱에서 마이크로서비스로 이전의 이점을 얻게 되었습니다.


이번에 참조한 글은 마이크로서비스 아키텍처에 대한 개괄적인 내용 및 우버의 간략한 사례를 포함하고 있는데 추후 기회가 된다면 마이크로서비스 아키텍처에 대한 좀 더 상세한 개발 내용이 포한됨 사례를 찾아서 소개해 볼까 합니다. 



https://brunch.co.kr/magazine/mdstory  

마켓디자이너스 매거진 구독해주시면 업데이트 내용을 더욱 빨리 만나실 수 있습니다.  


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari