성장, 그리고 노력

부족하더라도 어제보다 더 잘해지자. 노력은 절대 배신하지 않는다.

도구, 기술, 이론/이론

모놀리식 아키텍처와 마이크로 서비스 아키텍처의 장점과 단점

제이콥(JACOB) 2020. 8. 17. 21:43

 마이크로 서비스 패턴의 필요성을 언급하라고 하면, 제일 먼저 나오는 패턴이 큰 진흙 공(Big ball of Mud) 패턴이다. 딱 봐도 좋은 느낌은 아니다. 하지만 하나의 WAR 파일 하나로 애플리케이션을 패키징 하는 모놀리식 패턴 대부분 겪고 있는 문제이기도 하다. 비단 작은 회사들의 문제만은 아니다.

 A Big Ball of Mud is a haphazardly structured, sprawling, sloppy, duct-tape-and-baling-wire, spaghetti-code jungle. These systems show unmistakable signs of unregulated growth, and repeated, expedient repair. Information is shared promiscuously among distant elements of the system, often to the point where nearly all the important information becomes global or duplicated.
The overall structure of the system may never have been well defined.
If it was, it may have eroded beyond recognition. Programmers with a shred of architectural sensibility shun these quagmires.
 Only those who are unconcerned about architecture, and, perhaps, are comfortable with the inertia of the day-to-day chore of patching the holes in these failing dikes, are content to work on such systems.

— Brian Foote and Joseph Yoder, Big Ball of Mud. Fourth Conference on Patterns Languages of Programs (PLoP '97/EuroPLoP '97) Monticello, Illinois, September 1997 

위키디피아의 설명을 가져왔다. 쉽게 말해 진흙 공에 진흙을 아무리 많이 붙여도 진흙 공이라는 말이다. 

 물론 그 진흙공이 지금 우리 회사의 매출을 가져다주고 있다. 당장 이게 문제이고 이거를 계속 유지하면 우리의 서비스를 망한다! 이런 말을 하고 싶은 게 아니다. 하지만, 이렇게 계속 진흙을 붙이다 보면, 우리 애플리케이션은 갈수록 복잡해지고  애자일 방법론을 도입한다고 한들, 개발 속도는 더 느려지고 비즈니스 목표 달성은 거의 불가능에 가까워진다. 

 모놀리식 아키텍처가 본질적으로 나쁘다는건 아니다. 서비스가 작았을 때는 그것이 최선의 선택이었을 것이다.

 

모놀리식 아키텍처의 장점

- 개발이 간단하다 -> 개발 툴이 단일 애플리케이션 구축에 초점이 맞춰져 있다.

- 애플리케이션을 쉽게 변경할 수 있다 -> 코드, DB 스키마를 변경해서 빌드/배포가 편하다.

- 테스트하기 쉽다 

- 배포하기 쉽다 -> 서버에 접속하여 WAR 파일을 복사하면 된다

- 확장하기 쉽다 -> 로드 밸러서(load balancer) 등을 이용하여 확장이 쉽다.

 

하지만 우리의 서비스가 커질수록 위의 장점은 빛을 잃어가기 시작한다.

 

모놀리식 아키텍처의 한계

개발팀이 스트린트(sprint)를 할때마다 추가 구현할 스토리가 늘어나고, 그만큼 코드 베이스와 관리 오버헤드 역시 증가한다. 애플리케이션은 너무 크고 복잡해져서 몇몇 초기 개발자를 제외하곤 완전히 이해할 수 없을 정도이다. 버그를 고치고 새 기능을 정확하게 구현하기가 갈수록 힘들고 시간도 오래 걸리기 시작하는 것이다.

 코드베이스는 갈수록 이해하기 힘들어지고, 코드를 변경하거나 추가할 때마다 코드 베이스는 한층 더 복잡하고 난해한 코드로 뒤덮인다. 처음 모놀리식 아키텍처를 설계했을 때는 깔끔하게 모듈화 한 아키텍처였지만, 점점 큰 진흙 공이 되어버리는 것이다. 

 개발 자체도 느려진다. 너무 큰 애플리케이션 때문에 IDE의 실행 속도도 현저히 느려지고, 빌드 시간도 당연히 오려걸린다. 코드 수정 후 빌드, 테스트하기까지 너무 많은 시간과 노력이 들어 생산성이 떨어지게 된다. 또한 코드 베이스가 너무 복잡하여 변경 영향도가 제대로 파악이 안 되므로 개발자의 테스트 시간과 테스트에서 문제 발생 시 수정까지의 사이클도 길어진다.

 테스트시에도 시간이 오래걸리고, 코드 베이스는 복잡해지다 보면, 애플리케이션의 신뢰성이 떨어지게 된다. 애플리케이션이 너무 크다 보니 철저하게 테스트하기 어렵고, 이는 프로덕션에서 버그가 가능성도 높이게 된다. 

 전체 모듈이 같은 프로세스로 실행되다보니 결함 격리(fault isolation)가 되지 않고, 모듈에 버그 하나만 있어도 메모리 누수가 발생해서 전체 애플리케이션 인스턴스가 내려가는 일도 다반사이다. 

 마지막으로 기술 스택이 초기 기술 스택으로 고정되어 있다. 더 좋은 기술, 더 안정적인 새로운 기술이 나오더라도 전체 모놀리식 애플리케이션을 재작성하는 비용과 리스크를 고려하여 기존 기술 스택을 계속 유지해야 한다. 점점 안 쓰는 기술 스택으로 작성된 애플리케이션이라도 계속 유지해야 한다. 

 


 여기까지 글을 읽었는데, 지금 개발하고 있는 공감할 수 있다면 이미 모놀리식 아키텍처를 통한 개발을 하고 있을 확률이 높다. 그렇다면 이 문제를 어떻게 해결해야 될까? 지금 나온 해결책 중에 가장 관심이 가는 해결책이 이 글의 제목인 "마이크로 서비스 아키텍처"이다.

출처: AWS

마이크로서비스가 대체 뭔데?

마이크로 서비스는 소프트웨어가 잘 정의된 API를 통해 통신하는 소규모의 독립적인 서비스로 구성되어 있는 경우의 소프트웨어 개발을 위한 아키텍처 및 조직적 접근 방식입니다. 이러한 서비스는 독립적인 소규모 팀에서 보유합니다.

 위 정의는 AWS에서 정의한 내용이다. 쉽게 말해 하나의 애플리케이션을 여러 서비스로 기능 분해하는 아키텍처라고 보면 된다. 이 아키텍처는 서비스를 모듈성(modularity)의 단위로 사용하고, 각 서비스는 다른 서비스가 함부로 넘어오지 못하게 각각의 API를 제공하며 우회하여 접근할 수 없게 한다. 서로 느슨하게 결합되어 있고 오직 API를 통해서만 통신하는 것이다. 

 이렇게 느슨하게 결합된 서비스는 각각 자체 DB를 가지게 된다. 회원 서비스라면 USERS 테이블을 소유하는 것이다. 이렇게 하면 개발시 본인이 담당한 서비스 스키마를 다른 서비스 개발자와 일일이 협의하지 않고도 변경할 수 있고, 런타임에 서비스는 완전히 분리되어 있기 때문에, 이를테면 다른 서비스가 DB Lock을 획득해 내 서비스를 블로킹(차단, blocking)하는 일은 생기지 않는다. (참고로 서비스마다 자체 DB 서버를 설치해야 된다는 의미는 아니다. 각자 자제 도메인 모델을 소유하는 것이다.)

 

FTGO 마이크로서비스 아키텍처 예제

출처: https://learn.co/lessons/microservices-patterns-chapter-1-2

 퍼사드(facade) 역할을 하는 API 게이트웨이는 REST API를 제공하고 이 게이트웨이로 들어온 요청을 각각의 서비스로 보내게 된다. 서비스는 각자의 API를 통해 움직이게 된다.


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

- 크고 복잡한 애플리케이션이라도 지속적인 배포(CD)가 가능하다.

- 각각의 서비스로 나뉘다 보니 단일 서비스의 규모는 작아지기 때문에 관리하기가 쉽고, 개발자도 담당 서비스의 코드 베이스만 이해하면 되면서 IDE도 느려지지 않아 생산성이 올라간다.

- 서비스를 다른 담당 서비스 개발자와 협의없이 독립적으로 배포/확장할 수 있다.

- 모든 팀은 독립적이고 자율적으로 움직일 수 있고, 개발 속도도 더 빨라진다.

- 결함 격리가 잘 되기 때문에, 한 서비스에서 메모리 누수가 발생하더라도 다른 서비스에 영향을 주지 않는다. 

- 새로운 기술을 서비스 별로 실험하고 도입하기 좋다. 이 말은 즉 서비스에 맞는 언어와 프레임워크를 각각 선택할 수 있게 되는 것이다. 또한 서비스 규모가 작기 때문에 더 나은 언어와 기술로 재작성하는데 드는 비용과 리스크도 훨씬 적다. 

 

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

- 분산 시스템을 테스트하기가 어렵다. 각 서비스의 테스트는 쉬워지지만, 여러 서비스가 연관된 테스트를 진행하고 자동화하는 것도 쉬운 일이 아니다. 

- 적절한 서비스로 분해하는게 쉽지 않다. 잘못 분해하면 결합도가 높은 서비스들로 구성된 분산 모놀리스를 구현하게 될 수도 있다. 

- 여러 서비스에 걸친 기능을 배포할 때 사전 조율을 잘하여야 한다. 

- 도입 시점을 검토하는 것이 쉽지 않다. 사업의 초기에는 도입할 이유가 거의 없다. 오히려 개발 속도만 느려질 뿐이다. 

- 마이크로서비스 도입에 따른 다양한 설계/아키텍처 이슈를 해결해야 하며, 완벽한 해답이라는 게 없다. 설계하기 나름인 것이다.

반응형