해당 글은 마이크로서비스 아키텍처(MSA) 사용에 대한 지극히 개인적인 후기를 작성하였습니다.
이상적인 MSA 사용은 무엇일까요? 제가 생각하는 시나리오는 아래와 같습니다.
그러나 현실에서는 이런 아름다운 시나리오로 MSA를 도입하는 것은 유명한 기업이나 급성장하는 유니콘 기업이 아니라면 어려울 것으로 생각됩니다.
그래서 저는 위의 시나리오와 전혀 관련이 없으며 서비스 규모가 크지 않고 사용자가 적은 프로젝트에서 MSA를 적용한 경험을 공유하고자 합니다.
제 업무는 IoT
디바이스에서 들어온 데이터를 가공하고, 이를 활용하여 프로젝트에 필요한 기능을 구현하는 것이었습니다. IoT
디바이스의 다양성으로 인해 데이터 수집을 위하여 서비스에 기능이 추가 될 때가 많았는데요. 이로 인해 첫 번째 장점을 경험하게 되었습니다.
일반적으로 하나의 서비스에 작은 기능을 추가할 때도 아래와 같은 과정을 거치게 됩니다.
만약에 모든 서비스가 하나로 통합된 모놀리식 구성이였다면, 빌드 및 배포 과정에서 상당한 시간이 소요되었을 것입니다.
하지만 데이터 가공을 위한 서비스에만 기능을 추가하고 배포하다보니, 기능 구현 부터 테스트 까지의 과정이 효율적으로 느껴졌습니다.
웃픈 이야기 이지만 꽤 자주 발생하는 상황입니다.
각 서비스들이 독립적으로 이루어지기 때문에, serviceA
에서 오류가 난다고 serviceC
에 영향을 끼치지 않습니다. (다만, 두 서비스 간 데이터 교환이 있는 경우에는 다를 수 있습니다.)
예시를 들어보겠습니다.
serviceA
는 사용자 관리 서비스이다.servicdC
는 IoT
디바이스에서 데이터를 수집하는 서비스이다.serviceA
가 다운되었음을 확인했다.serviceC
는 독립적인 서비스 이므로 주말 동안 데이터 수집은 정상적으로 이루어졌다.간단하게 말하면, 사용자가 회원 가입을 하다가 오류가 나도 데이터 수집 서버에 영향을 미치지 않는다는 것입니다.
만약에 이 상황이 모놀리식 구성이었다면, 서비스 전체가 중단돼 주말 동안 데이터 수집이 불가능 했을 수도 있습니다.
앞서 언급한 첫 번째 장점과 유사한 내용입니다.
serviceA
의 기능 구현 및 테스트serviceB
의 기능 구현 및 테스트serviceC
의 기능 구현 및 테스트각 서비스는 독립적으로 운영되기에 기능 구현 작업이 동시에 이루어질 수 있습니다. 또한 독립된 환경에서 각자가 원하는 테스트를 개별적으로 진행할 수 있게 됩니다.
물론 이 내용은 모놀리식 구성이여도 가능하지만 첫 번째 장점에서 언급한 배포가 효율적이므로 따라오는 부가적인 기능이라고 보시면 될 것 같습니다.
조금 유식하게 말해보자면 "개발 및 테스트가 병렬적으로 진행되고 팀 전체의 개발 생산성이 향상된다!"
serviceA
에서 오류가 발생했다면 serviceA
만 확인하면 됩니다. (물론 데이터 교환이 이루어지는 서비스라면 다른 서비스도 확인하여야 합니다.)
모놀리식 구성일 경우 하나의 서비스에서 나오는 로그의 양만해도 엄청난데요.
독립적인 서비스로 여러개를 구성할 경우 해당하는 로그만 모니터링 할 수 있고, 이로써 문제 해결에 들이는 시간과 노력이 상당히 절약됩니다.
또한 유연한 롤백이 가능합니다.
serviceA
는 사용자를 관리하는 서비스로 이번에 마이페이지 기능을 추가하였다.serviceA
의 새로운 이미지를 만들고 1.0.0
버전을 1.1.0
으로 변경하였다.serviceA
의 버전을 1.0.0
버전으로 롤백시킨다.한 줄로 말하면 오류가 발생하면 이 전 버전의 이미지를 사용하면 된다!
이러한 롤백 과정도 모놀리식 구성에서도 가능한 일이지만 그 과정이 효율적이지 않습니다. (첫 번째 참고)
지극히 개인적인 경험입니다.
교육(?) 이라고 하면 너무 거창한 단어 같지만, 아래와 같은 상황이 있었습니다.
serviceE
를 개발할 수 있게 도와준다.serviceE
개발을 완료했다.이처럼 실제로 프로젝트를 배포하는 경험을 제공하고 업무 흐름을 이해하는 데 큰 도움을 줄 수 있었습니다.
정말 쓸 데 없는 내용일 수도 있지만 진짜 기분이 좋습니다.
요즘 IT 회사의 우대사항에 MSA는 정말 자주 언급되고 이를 경험해보지 못해 아쉬운 신입, 주니어 개발자분들이 참 많다고 생각되는데요.
내가 그래도 요즘 선호하는 기술을 사용하고 있구나 하는 뿌듯함을 느낄 수 있었습니다.
이러한 효과가 업무 효율성에 큰 영향을 끼쳤다고 생각됩니다.
이렇게만 보면 MSA는 뭔가 완벽하고 안 할 이유가 없을 것 같지만 단점도 분명히 존재합니다.
이제는 제 경험을 바탕으로 한 MSA에 대한 단점을 적어보겠습니다.
개인적으로 가장 큰 단점이었습니다. 크게 두 가지로 분류할 수 있겠습니다.
운영 복잡도
독립적인 서비스를 여러개 사용하다보니 여러가지 툴(도커, 쿠버네티스, GitHub Actions등)을 관리하는 초기 설정 과정에서 시간과 노력이 많이 들어가고 운영에 대한 복잡도가 증가합니다. 가끔씩 내가 툴을 다루는 사람인지 백엔드 개발자인지 헷갈릴 때가 있었습니다.
통신 프로토콜 gRPC
효율적이고 안정적인 통신을 기대하며 서비스간의 통신을 gRPC
를 도입한 결과 이로 인한 추가적인 공부가 필요했습니다. 예시로 gRPC
의 특징에 대한 공부와 프로토콜 버퍼 작성방법 등이 있었습니다.
회사의 관점으로 가장 큰 단점이었습니다.
MSA구성할 때, EKS
를 사용하였습니다. 어느날 궁금하여 '해당 프로젝트를 모놀리식으로 변경하여 하나의 ECS
를 사용한다고 가정하면 비용이 어떻게 될까요?'를 선배 개발자분에게 여쭈었더니 꽤 많은 비용 차이가 발생한다는 것을 알게 되었습니다.
이는 아래 두가지를 잘 고려하여 선택해야 될 것 같은 느낌이 크게 들었습니다.
상대적으로 높은 생산성과 많은 돈
vs 상대적으로 낮은 생산성과 적은 돈
단순히 'MSA가 좋고 익숙하다'는 이유로 해당 구조를 가져갈 경우 더 높은 비용 발생으로 인하여 내가 회사에 해를 끼칠 수 있겠구나를 생각해볼 수 있었습니다.
정리하자면 "클라우드 서비스를 사용하는 경우, MSA 도입으로 인한 인프라 및 운영 비용이 높아질 수 있다."
구글링을 하여도 많이나오는 MSA 단점 중 하나인 트랜잭션 관리의 어려움
과 관련된 내용입니다.
위 구조로 따지면 아래와 같겠습니다.
serviceA
에서 데이터를 가공하여 저장한 뒤 serviceB
로 전송하였다.serviceB
에서 해당 데이터를 처리하다 오류가 났다.serviceB
오류를 롤백한다.serviceA
에 저장된 데이터를 삭제한다.하나의 서비스에서 오류가 났을 때, 다른 서비스에서 일어난 변경 사항을 되돌리기가 어려웠고 이를 해결하기 위한 Saga Pattern
, 이벤트 소싱 등의 방법을 공부하고 적용하는 러닝커브가 높게 느껴졌습니다.
크게 두 가지로 분류할 수 있겠습니다.
애매모호한 역할과 책임
A
라는 기능은 serviceA
에 추가하는 것이 맞는가? 하는 상황이 꽤 자주 벌어졌습니다.
분리? 통합?
serviceA
에 넣어서 개발해보니, 실제로 serviceB
에 넣는게 더 맞는 판단이였고 종국에는 serviceA
와 serviceB
를 나누는 것이 아닌 두 서비스를 합친 serviceA+B
가 효율적인 경우도 있었습니다.
이러한 어려움을 충분한 고민과 회의를 통해 결정하지 않고 무작정 서비스를 분리한다면 구조의 한계를 느껴 일을 두 번 하는 경험을 하게 됩니다.
이번에는 MSA를 적용하면서 느낀 개인적인 생각과 아쉬운 점 등을 적어보겠습니다.
갑자기 이게 왜 나와? 하실수도 있겠습니다.
객체지향의 5대원칙 SOLID 중 S는 단일 책임 원칙을 나타냅니다.
간단히 말하면 하나의 클래스는 하나의 기능을 잘 수행하여야 한다는 의미인데요.
MSA를 구성하며 이 원칙이 더욱 크게 느껴졌습니다.
각각의 독립적인 서비스는 해당하는 기능을 잘 수행하여야 하고 개발자는 특정 서비스에만 집중할 수 있게 되었습니다.
수 많은 시행 착오를 거친 선배 개발자들이 S에 대해서 고민하다가 나온 것이 MSA가 아니였을까요?
맨 처음에 시작한 이상적인 시나리오 처럼 모놀리식의 한계를 느껴 MSA로 변경하고 트래픽이 증가함에따라 특정 서비스만 증설해보는 그런 과정을 해보지 못한 점이 아쉽습니다.
이 부분은 저 뿐만 아니라 수많은 주니어 개발자 분들이 공감하실거라 생각합니다.
두 번째 의견을 생각하면서 같이 떠오른 점입니다.
제가 경험한 바로는 트래픽이 어쩌고 저쩌고 말고도 MSA는 충분히 많은 장점이 있다고 생각됩니다.
자본이 충분하다면 프로젝트를 MSA로 구성하여 서비스마다 적당한 팀원을 배치하고 담당하게 한다면, 해당 서비스에 대한 전문성과 업무의 효율성이 좋아질 가능성이 매우 클 것이라 생각합니다.
간단하게 말하면 '팀에 인간이 많으니까 이를 적당히 나눠서 각 서비스에 배치시킨 뒤 해당 서비스 개발을 잘 하도록 하자.' 정도의 이유로도 충분히 사용 가치가 높지 않을까요?
비록 이상적인 환경에서의 사용은 아니였지만, 신입 개발자 때 궁금했던 MSA를 1년간 경험하며 많은 점을 느낄 수 있었습니다.
좋은 경험을 할 수 있게 시스템을 구축하고 도와주신 회사의 선배 개발자 분들에게 감사드립니다.