본문 바로가기

개발/Microservice architecture

MSA (Microservice Architecture) 마이크로서비스 아키텍처 회고

MSA를 적용하면서 느낀점과 MSA에 대한 생각을 정리하고자 합니다.

 

MSA(Microservice Architecture) 마이크로 서비스 아키텍처란?

간단히 말하면, 큰 어플리케이션을 작게 나누는 것이 전부입니다. 큰 것을 작게 나눠서 장점도 있지만 단점도 존재해요. 하지만 단점을 커버할 만큼 어플리케이션이 크다면 MSA를 적용하는 것이 좋습니다. 장단점을 간단하게 이야기하듯이 써내려가며 생각을 정리하고자 해요.

Monolithic Architecture 단일 아키텍처

대부분 모놀리틱 아키텍처라고 번역을 하는 것 같은데, 모놀리틱, 모놀리틱 하니까 뭔가 이상해서 단일 아키텍처라고 이름을 지었습니다. 단일 아키텍처를 예를들어 살펴봅니다. 아래와 같이 Coupang이라는 하나의 팀이 있습니다. 그리고 Coupang 팀은 상품 화면을 만들기 위해, 팀에서 가지고 있는 하나뿐인 데이터베이스에 존재하는 여러 테이블로부터 데이터를 가져옵니다. 단일 아키텍처의 장단점은 MSA에 대해 알아본 다음, MSA와 비교하면서 살펴봅니다.

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

마찬가지로 이해하기 쉽게 예를들어 봅니다. 아래 그림은 위 그림과는 달리 빨간 네모상자가 되게 많습니다. 각 상자는 컴포넌트를 의미하며 각 팀에서 관리합니다. 한 페이지는 아래와 같이 여러 팀이 협업해서 구성합니다. 각 팀은 팀 성격에 맞는 데이터베이스를 가지며 API나 메시징 큐를 통해 데이터를 다른 팀에 제공합니다.

MSA 장단점

어플리케이션의 빠른 성장

어플리케이션의 규모가 작을 경우 MSA를 적용할 필요도 없고 얻는 이점이 거의 없습니다. 오히려 MSA를 운영하는 비용이 더 큽니다. 하지만 단일 어플리케이션의 규모가 커지게 되면 답답한 상황이 발생합니다. 예를들어, Coupang팀의 어떤 개발자가 상품 페이지에 있는 제목을 하나 바꾸기 위해 배포를 시작합니다. 그런데 10분 뒤에 다른 사람이 상품 페이지에 있는 내용을 바꾸기 위해 배포를 하려고 합니다. 하지만 배포가 끝날 때 까지 기다려야 합니다. 이런 상황은 어플리케이션의 규모가 커질 수록 심각해지며, 이것은 어플리케이션이 빠른속도로 성장하는 것을 방해합니다.

MSA의 경우 각 팀에서 각 컴포넌트를 담당합니다. 각 팀은 데이터베이스도 따로 갖고, 소스코드 리포지터리도 따로 갖습니다. 다른 팀을 신경쓰지 않고 각 컴포넌트의 배포가 가능합니다. 따라서 다른 사람의 배포를 기다리지 않고 변경사항을 바로 적용할 수 있으며 따라서 어플리케이션이 빠르게 성장할 수 있습니다.

신기술 적용이 쉽다

MSA에서는 각 팀에서 컴포넌트를 담당합니다. 각 팀에서 어떤 기술을 사용해서 구현할지는 팀에 선택권이 있습니다. 단일 아키텍처의 경우 사용하는 기술이 바뀌면 모든 팀원이 움직여야 하기 때문에 신기술 적용이 어렵지만, MSA는 그렇지 않습니다.

어떤 팀에서 새로운 기술을 적용해서 성공하면, 공유 세션을 열어서 다른 팀에게 신기술을 전파할 수도 있습니다. 그리고 팀마다 사용하는 기술이 다르기 때문에 새로운 것을 해보고 싶은 개발자가 회사를 나가기보다, 팀을 이동하는 것도 장점이 될 수 있다고 생각합니다.

장애 추적이 어렵다

작은 단위로 팀이 나뉘어져 있다보니 어떤 기능이 동작을 안한다고 하면 여러 팀의 도움이 필요합니다. API를 이용한 동기 호출이면 그나마 장애 추적이 쉽지만, 대부분의 대용량 처리는 메시징 큐를 사용합니다. 메시징 큐는 비동기로 동작하기 때문에 장애 추적이 더 어렵습니다.

테스트가 어렵다

MSA에서는 팀이 서로 의지합니다. 따라서 팀에서 담당하는 컴포넌트를 테스트하기 위해 개발서버에서 동작시키려면 다른 팀으로부터 데이터를 얻어와야하기 때문에, 다른팀의 개발서버가 동작을 안한다면 테스트를 할 수가 없습니다. 아무래도 스피드가 생명인 비즈니스에서, 바쁘게 움직이다보니 개발환경에 신경을 덜 쓰게 됩니다. 따라서 무엇 하나 테스트를 하려고하면, 다른 팀의 API가 제대로 동작하지 않는 경우가 허다합니다.

트랜잭션 관리가 어렵다

담당자를 찾기가 어렵다.. 등등

여러가지 장단점이 있습니다. 최고의 장점은 어플리케이션의 빠른 성장이라고 생각합니다. 그리고 물론 단점도 여러가지가 있겠지만, 이번 포스팅에서는 MSA를 적용한 곳이라면 어디에서나 겪을 수 있는 단점 한 가지에 집중하고, 이를 해결한 방법에 대해 회고하고자 합니다.

API 호출이 너무 많아!

상품 정보 페이지를 담당하는 팀에서는 치코리타 상품에 대한 페이지를 그리고 싶을 뿐인데, 호출해야 하는 API 가 너무 많습니다. 실제로 10개가 넘는 API를 호출해야 했습니다. 게다가 한 팀에서만 이러한 문제가 발생하는 것이 아니라 상품 정보가 필요한 모든 팀에서 같은 문제를 겪습니다.

많은 API 호출로 인해 네트워크 IO 및 로딩 속도만 문제가 된다면, 캐시를 이용해서 처리를 할 수는 있습니다. 하지만 비단 이러한 문제 뿐만 아니라, 개발 속도를 느리게 합니다. 대부분 상품정보를 필요로 하는 팀에서는 상품명, 상품 카테고리, 남은 재고 개수 등 상품과 관련된 많은 정보가 필요합니다. 만약 상품 ID를 가지고 있다면, ID를 가지고 정보를 제공하는 API를 모두 호출해서 필요한 정보를 수집해야 합니다. 그리고 각 API는 서로 다른 팀에서 제공하기 때문에 어떤 정보를 어느 팀에서 제공하는지부터 찾아야 합니다. 그리고 어떤 정보는 심지어 두 개의 팀에서 제공하기도 해서 어떤 팀의 API를 사용해야 맞는지 문의를 해야할 때도 있어요.

그래서 이 문제를 해결하기 위해 다음과 같은 구조를 생각해냅니다.

간단히 말하자면, 통합정보 팀이 상품과 관련된 정보를 각 도메인팀에서 모아서 한 곳에 저장합니다. 그리고 통합정보 팀이 통합정보 API를 통해 도메인 팀에 상품 정보를 제공합니다.

조금 더 상세한 과정은 다음과 같습니다. 도메인 팀은 상품과 관련된 정보를 카프카로 전송합니다. 도메인 팀은 각 팀이 가지고 있는 상품정보가 업데이트 될 때마다 카프카로 바로바로 전송해야 합니다. 그래야 통합정보 팀에서 최신 상품 정보를 제공할 수 있습니다. 그리고 통합정보 팀은 스파크 스트리밍을 이용해서 각 도메인 팀에서 받은 상품정보를 활용하여 NoSQL 카산드라 테이블에 통합정보를 구성합니다. 스트리밍이기 때문에 실시간으로 최신정보를 카산드라 테이블에 구성할 수 있습니다.그리고 통합정보 팀은 카산드라 테이블을 읽어서 상품에 대한 통합정보를 가져올 수 있는 API를 제공합니다. 이제 도메인 팀은 통합정보 API 하나만 호출하면 상품과 관련된 모든 정보를 얻어올 수 있어요.

하지만 이 과정에서도 어려움이 있었어요. 모든 팀이 짠!하고 통합정보 팀이 제공하는 새로운 API를 사용하면 참 좋겠지만, 이미 MSA를 적용해서 10개 이상의 팀이 생긴 상황에서 한번에 새로운 API로 마이그레이션을 하는 것은 거의 불가능에 가까웠습니다.

같은 상품인데, 페이지마다 정보가 달라!

통합정보 팀이 새로운 API를 제공하기 시작했습니다. 그리고 각 도메인 팀은 이제 쉽게 상품 정보를 얻어올 수 있기 때문에 새로운 API로 마이그레이션을 시작합니다. 상품 정보를 얻기 위해 API를 10개나 호출하던 코드를 새로운 API 한 번으로 대체합니다. 너무 편합니다. 그런데 문제가 발생하기 시작합니다. 바로 마이그레이션 과도기인 것입니다.

그리고 이슈가 발생했습니다. 통합정보 API로 마이그레이션을 아직 하지 않은 팀에서는 배송팀으로부터 상품의 배송일 정보를 가져오고 있었습니다. 그리고 통합정보 API로 마이그레이션을 완료한 팀에서는 통합정보 API에서 배송일 정보를 가져옵니다. 배송일 정보를 제공하는 팀이 두 곳이 된 것입니다. 그리고 MSA로 각 페이지마다 팀으로 분리가 됬기 때문에, 특정 페이지에서 배송일 정보를 화면에 그리기 위해 어떤 팀의 API를 사용하는지 알 수 없었습니다. 따라서 먼저 회사 전체 메일을 통해 어떤 페이지에서 어떤 API를 사용하는지 조사가 필요했습니다.

문제는 계속됩니다. 배송일 정책이 바뀌어서 배송일을 계산하는 로직을 변경해야 했습니다.배송일은 계산하는 같은 로직인데 통합정보 팀, 배송팀 두 곳에서 변경이 필요했습니다. 뿐만 아니라, 배포도 문제가 됬습니다. 배송일은 민감합니다. 사용자가 A 페이지에서는 상품이 내일 도착한다고 해서 주문했는데, B 페이지에서 이틀뒤에 도착한다고 하면 문의가 많이 늘겠죠. 그래서 배송일 정보를 제공하는 두 팀이 동시에 변경된 로직을 적용해야 했습니다.

물론 아직은 과도기라 이런 현상이 발생한 것이라 생각할 수도 있어요. 그런데 우리는 빠르게 변화하는 비즈니스 환경에서 매일마다 수 많은 요구사항을 받게됩니다. 제한된 리소스로 인해, 수 많은 요구사항 중에서 우선순위를 정해서 필요한 것을 먼저 수행합니다. 그런데 돈이 되는 비즈니스의 성격이 거의 없는 마이그레이션 작업이기 때문에 힘을 줘서 다함께 마이그레이션하는 것이 사실상 불가능합니다.

MSA를 적용하면서 얻은 다른 느낀점도 많겠지만, 시간이 늦은 관계로 우선은 여기까지만 정리하려 합니다.