들어가기
프로젝트를 진행할 때마다 항상 갖는 궁금증이 있었다.
다른 언어를 주로 사용하는 사람들끼리는 프로젝트를 어떻게 함께 진행할까?
전체 기능 중 일부만을 수정하기 위해 전체 기능을 담당하는 사람들이 이를 인지하고 대비하여야 하는 것인가?
수백 명의 백엔드 개발자들이 하나의 커다란 프로젝트로만 진행을 할 수밖에 없는 것인가?
이러한 것들을 해결하기 위한 방식이 바로 MSA인 것이다.
MSA는 'Mircro Service Architecture'의 약자로 기준 별로 애플리케이션들이 분리되어 전체 서비스를 이루는 개발 방식이다. 그렇다면 MSA를 사용하기 전인 하나의 거대한 서비스를 가지는 것을 무엇이라 하는가?
바로 '모놀리식 아키텍처'라고 한다. 모놀리식 아키텍처란 용어는 MSA의 반대되는 개념으로 전통의 아키텍처를 지칭하는 의미로 생겨난 단어이다. 즉, MSA라는 용어가 나온 후에 모놀리식 아키텍처란 용어가 생긴 것이다.
MSA 방식으로 개발을 한다면 서로 다른 언어를 사용해도 기준 별로 다른 애플리케이션을 구동하므로 문제없고, 수백 명의 개발자들이 팀 단위로 각각의 애플리케이션을 담당하고, 특정 기능을 수정할 때 전체 서비스의 장애를 고려할 필요가 없는 것이다.
그렇다면 이러한 MSA 방식이 무조건 옳은 것인가?
그것 또한 아니다. MSA 방식을 사용하는 것에도 문제가 있기 때문에 MSA 방식으로 개발을 시작할지, 모놀리식 방식에서 MSA 방식으로 전환할지 등 많은 고민이 필요하다고 한다.
이 글에서는 모놀리식 방식과 MSA 방식에 대하여 공부한 내용을 작성하였다.
주로 '김병규', '김성진'님의 패스트 캠퍼스 강의를 참고하였다.
모놀리식 아키텍처
MSA와 비교한 모놀리식 아키텍처의 특징
위에서 언급했다시피 모놀리스 아키텍처는 MSA가 나오기 전에는 존재하지 않는 용어였다.
모든 종류의 서비스가 하나의 애플리케이션으로 구성되어 있는 아키텍처로 하나의 주요 프로세스로 구성된다.
하나의 DB endpoint를 사용한다는 점에서 MSA와 차별이 된다.
아래의 사진을 봐보자.
위의 사진과 같이 모놀리식 아키텍처는 하나의 거대한 서버와 데이터베이스를 가지고 있다.
MSA 방식은 여러 개의 작은 서버들과 서버 별 각각의 데이터베이스를 가지고 있다.
MSA가 대세라고는 해도 여전히 모놀리식 아키텍처를 많이 사용할 만큼 여러 장점들이 있다.
가장 큰 특징은 MSA 보다 쉽다는 것이다.
배우고 다루기가 쉽고 배포가 간단하고 어디서 패키징해도 상관없으며, 어떻게든 배포만 하면 된다.
유지보수는 위의 사진만 봐도 알 수 있듯이, MSA 보다 훨씬 간단하기에 더 쉽다.
비싼 서버 리소스를 최적화해서 사용이 가능하며 공통 모듈 등 활용하기가 쉽다.
그렇다면 어떤 경우에 모놀리식 아키텍처를 사용하는 것이 좋을까?
- 창업 혹은 새로운 서비스를 시작하는 경우
- 클라우드 환경을 사용하기 어려운 경우(ex. AWS)
- 소수의 팀원으로 빠르게 오픈해야 하는 경우(협업이 적을 수 있는 경우)
- 금융 등 보안과 안정성이 최고로 중요한 경우
- 개발자들의 역량이 비교적 낮을 경우
- Devops 등 전문 인력이 부족할 경우 - CI/CD 파이프라인 등의 구축이 어려울 경우
4번 항목 같은 경우 정말 중요한 정보들은 클라우드 환경보다 온프레미스 환경에서 다루는 것이 좋은 선택일 수 있다.
MSA 방식을 제대로 사용하기 위해선 클라우드 환경에서 배포를 해야 하기에 온프레미스 환경에서 사용하기 용이한 모놀리식 아키텍처를 사용하는 것이다.
계속 장점만 얘기했지만, 단점 또한 당연히 존재한다.
• 우선 수평 확장(Scale Out) 이 어려운 점이다. 단일 데이터베이스를 사용한다면 이를 늘리는 것은 고려해야 할 점이 많다. 단순히 크기를 키우는 수직 확장(Scale Up)과 다르게 수평 확장은 복제본을 늘리는 것으로 복제본끼리 데이터는 어떻게 공유할 것인가 등의 문제가 수반된다.(NOSQL의 경우 수평 확장이 SQL보다 용이하다고 해도 MSA처럼 서비스 별로 DB가 나눠져 있는 것이 아니기에 수월하지 않다.)
• 그리고 규모가 커질수록, 하나의 애플리케이션에서 감당하는 것이 많아지므로 복잡성이 증가하여 수정에 대한 부담이 증가한다. 이는 유지보수 비용의 증가를 의미한다. 모놀리식 환경이 보편화되고, 시스템이 커질수록 커뮤니케이션 비용이 기하급수적으로 늘어난다. 규모가 커짐에 따라 애플리케이션 구동 시간이 늘어나고 빌드, 배포 시간 또한 길어진다.
• 무엇보다도 일부분의 장애가 있다면 전체 애플리케이션에 영향을 끼치고, 일부분의 수정사항은 전체 애플리케이션을 다시 빌드하고 배포해야 한다.
• 마지막으로 기능별로 알맞은 기술과 언어, 프레임워크를 정하는데, 개발하는 모든 인원이 같은 언어를 사용해야 하는 점이 고려사항이다.
아래는 모놀리식 아키텍처를 채택할 경우 단점이 있는 경우들이다.(이는 MSA를 채택해야 하는 이유가 될 수 있다.)
- MSA, Cloud 환경에 충분히 숙련된 개발자들이 많은 경우
- 많은 서비스가 식별이 되어 동시 다발적으로 개발을 진행하는 경우
- 보안과 안정성보다는 빠른 기능 개발과 배포가 중요한 서비스인 경우(Agile)
- Devops 등 전문 인력이 충분하고, 개발자들이 CI/CD 파이프라인에 대해서 어느 정도 이해가 있는 경우
정리하자면 모놀리식 아키택쳐는 안정성, 보안성, 편의성에서 장점을 얻을 수 있고,
애자일, 확장성, 유연성 측면에서 단점이 되는 것과 동시에 MSA를 채택하여 생기는 장점이라 할 수 있다.
SOA( Service Oriented Architecture )
MSA 얘기 중 뜬금없이 SOA가 나와서 당황스러울 수 있는데, 흐름을 이해하는데 좋겠다고 생각하여 간단한 내용들을 추가하였다.
모놀리식 아키텍처에서 바로 MSA로 간 것은 아니다. 모놀리식 아키텍처 → SOA → MSA로 변화가 일어난 것이다.
SOA는 ' Service Oriented Architecture'의 약어로 '서비스 지향 아키텍처'라고 할 수 있다.
모놀리식 아키텍처의 단점들을 제한적인 환경에서나마 해결하고자 했던 노력에서 나온 아키텍처로 재사용성과 상호 운영성을 고려하여 나온 아키텍처이다.
동일한 기술 스택으로 '서비스' 단위로 개발하며 각 서비스들 간의 재사용이 목적이다. 서비스 간 규격화된 프로토콜(인터페이스)을 사용하여 통신을 한다.
ESB(Enterprise Service Bus)라는 개념을 통해, 특정 요청에 대해 어떤 서비스들을 호출할지 캡슐화된 Layer가 존재한다.
아래의 사진을 봐보자.
공통적인 데이터베이스를 사용하는 점에서 모놀리식 아키텍처와 같지만, SOA는 Service들을 독립적으로 배포할 수 있고 비즈니스 로직에 따라, 어떤 서비스를 호출할지 결정하는 ESB가 있는 Layer가 존재하는 점에서 다르다.
SOA 또한 모놀리식 아키텍처의 단점을 해결해주지 않는가?
하지만 SOA 완벽하다면 MSA가 나올 필요가 없었다.
아래의 사진을 봐보자.
SOA는 개발의 단위를 '서비스'로 인지하여 다른 서비스와 독립적으로 개발하고 배포할 수 있다는 점에서 MSA와 같다.
하지만 MSA는 비즈니스 로직(서비스)의 재사용을 지양하여 서비스 간 결합도를 낮추는 것이 목표이다.
결국 낮은 결합도로 변화에 빠르게 대처할 수 있는 Agile 한 방식의 개발할 할 수 있는 것이다.
또한 각기 다른 기술스택으로 서비스를 구현할 수 있으며, 서비스 간 자유로운 방식(HTTP, gRPC, Kafka 등)으로 통신이 가능하다는 점에서 SOA와 다르다고 볼 수 있다.
결정적으로 SOA는 ESB라는 것이 있는데, 이는 결국 실행 중인 프로그램을 누군가는 관리하고 유지보수를 해야 한다는 것이다.
즉, SOA는 모놀리식을 호출하는 것을 고도화한 것뿐, 별반 차이는 없었던 것이다.
모놀리식과 SOA의 문제는 협업, 커뮤니케이션, 확장성, 유연성, 결합도, 응집도, 빌드와 배포 등을 가질 수 있다.
핵심은 요즘 시대에 요구사항 변화에 빠른 대처가 필요한 서비스 개발이 이루어져야 하였고, 이는 Agile 한 개발이 필요한 것이다. 그렇게 해서 나온 것이 MSA이다.
MSA
사실 MSA는 예전부터 있는 용어이다. 하지만 불편함 점들이 있었기에 모놀리식을 더 선호하였다.
MSA는 다양한 서버를 운용하기에 클라우드 환경이 매우 유용하다. 하지만 예전에는 클라우드 환경이라는 개념 자체가 별로 없었고 IDC(Internet Data Center)를 사용하는 것이 당연한 문화였다.
또한 모놀리식 환경에서의 개발 노하우들을 쉽게 버리기 힘들었고, 많은 서버들에 다양한 서비스들을 배포한다는 개념은 굉장한 리소스를 수반한다고 생각을 하였다.
그러던 중 AWS(Amazon Wer Services)가 등장하며 주요 환경이 온프레미스 환경에서 클라우드 환경으로 변화되었다. 아마존은 IaaS(Infrastructure as a Service), PaaS(Platform as a Service), SaaS(Software as a Service)를 제공하였으며 대표적으로는 EC2(클라우드에서 가상 서버를 구축하고 실행할 수 있는 서비스)가 있다.
필요에 따라 원하는 성능과 운영체제를 사용하고 유연한 스케일링을 가능하게 하였기에 서버 인프라 관리를 위한 시간과 비용이 감축될 수 있었다. 여기에 컨테이너 가상화 기술인 'Docker'와 오케스트레이션 도구(ex. 쿠버네티스)들의 발전으로 MSA가 사용되기 적절한 환경들이 만들어졌다.
하지만 모놀리식에 없어도 될 것들이 많이 사용되면서 운영 측면에서 쉬웠던 것들이 MSA에 와서는 더욱 어려워지는 문제가 있다.
아래의 사진을 봐보자.
한눈에 봐도 복잡한 메커니즘으로 이루어져 있다.
MSA를 잘 다루기 위해선 데비옵스의 영역이 중요해진 것이다.
그렇다면 어떻게 구현해야 MSA라고 할 수 있을까?
MSA라는 개념과 관련해서 많은 이론들을 만들어낸 마틴 파울러가 정의한 MSA의 특징들을 봐보자.
1. Componentization via Services(서비스를 통한 구성요소화)
각 구성별로 서비스로 만들어 독립적인 개발을 이루게 한다.
2. Organized around Business Capabilities(비즈니스 능력을 중심으로 한 조직화)
비즈니스 능력을 기준으로 팀을 구성한다. Business Capabilities는 조직이 얼마나 빠르고 유연하게 변화에 대응할 수 있는지에 대한 능력이라고 할 수 있다.
3. Product, Not Project(프로젝트가 아닌 제품으로)
프로젝트는 1회성으로 개발 이후 운영, 유지보수로 넘어간다. 하지만 프로젝트가 아닌 제품으로 보고 지속적으로 개발과 운영, 유지보수를 하는 것이다.(Waterfall 방식이 아닌 Agile 방식)
4. smart endpoints and dump pipes(스마트 앤드포인트 및 단순한 파이프라인)
복잡하지 않고 단순한 방식을 통해 통신을 한다.(Rest API, Kafka 등) SOA의 ESB는 smart pipes라고 하며 MSA 원칙과 맞지 않는다. 복잡한 로직은 뒤에서 하고 통신을 할 때는 단순하게 하자는 것이다. 관심사의 분리라고 할 수 있다.
5. Decentralized Governance(분산된 통치)
각 서비스별 적합한 언어와 프레임워크를 사용하는 등 최적의 기술스택을 사용할 수 있다.
6. Decentralized Data Management(분산데이터 관리)
각 서비스별 자체적인 데이터베이스를 사용하여 데이터 유연성, 탄력성을 확보하고 자원을 효율적으로 사용할 수 있다.
7. Infrastructure Automation(인프라 자동화)
CI/CD 파이프라인과 같이 인프라 자동화의 중요성이 강조된다. 복잡한 아키텍처를 최대한 단순하게 사용가능한 기술들이 핵심이다.
8. Design for Failure(고장을 위한 설계)
각 서비스는 장애 가능성을 항상 생각하여 이를 조치하고 복원할 수 있어야 한다. (ex. Circuit Breaker를 통한 감지, Container Ochestration, K8S를 통한 복원, Transaction을 통한 의도치 않은 결과 방지, Chaos Test를 통한 서비스 간의 영향도 확인)
9. Evolutionary Design
모놀리식 아키텍처에서 MSA 방식으로의 구조적 변환
결론
이렇게 간단하게 모놀리식 아키텍처와 MSA에 대해 정리해 보았다.
요즘 MSA가 대세라고 하여 공부를 해보았지만 파고들수록 어려운 지식들이 넘쳐나는 것이 MSA 인 것 같다.
그럼에도 대규모 프로그램에선 MSA 방식의 개발이 더 효율적이라는 것을 알기에 더욱 공부를 해봐야겠다.
참고
https://blog.voidmainvoid.net/226
https://www.ibm.com/kr-ko/topics/soa
https://martinfowler.com/articles/microservices.html