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

이글은 Why Microservices?(https://dzone.com/articles/microservices-basics?edition=213185)의 번역글 입니다. 해당 기사는 마이크로서비스 아키텍처를 적용할 때의 장점과 단점 모두를 많은 사람들이 익숙한 모놀리스(monolithic) 방식의 소프트웨어와 비교해 개략적으로 설명하고 있습니다. 혹시라도 번역에 대한 오류, 오타등을 발견하시면 댓글에 남겨주시길 부탁드립니다. 이 번역글을 읽고 나서 마이크로서비스에 대해 좀 더 자세한 글을 원하시면 MORE AGILE: 마이크로서비스가 가져올 미래의 개발 패러다임 글을 한 번 읽어보시길 추천드리고 싶습니다.

Popit 서비스내에는 다음 글을 읽어보세요.

http://www.popit.kr/마이크로서비스-아키텍처-그것이-뭣이-중헌디/

넷플릭스, 아마존 같은 회사들은 그들의 제품에 마이크로서비스(Microsservice) 개념을 적용 했습니다. 마이크로서비스는 소프트웨어 산업에서 가장 뜨거운 주제 중 하나이며 많은 기업들이 마이크로서비스를 도입하고 싶어합니다. 특히 마이크로서비스는 데브옵스(DevOps)와 매우 잘 어울립니다.

하지만 마이크로서비스란 무엇일까요? 기업들이 마이크로서비스를 적용해야 하는 이유가 무엇일까요? 마이크로서비스의 정의와 적용해야하는 이유를 이해하기 위해서 먼저 모놀리스 방식의 소프트웨어를 살펴보겠습니다.

모놀리스 방식의 소프트웨어에서는 주로 3계층(3-tier) 아키텍처를 사용 합니다.

  • 프리젠테이션 계층
  • 비즈니스 계층
  • 데이터 접근 계층

전통적인 웹 애플리케이션 클라이언트(브라우저)가 요청을 전송했다고 가정 해봅시다.  비즈니스 계층은 비즈니스 로직을 실행하고, 데이터베이스에서 특정 데이터를 불러오고/저장하고, UI를 통해 데이터를 사용자에게 보여줍니다.

그러나 여기에는 3계층 시스템이 가지고 있는 몇 가지 문제점이 있습니다. 모든 코드(프리젠테이션, 비즈니스, 데이터 접근)가 같은 코드베이스를 통해 관리 됩니다. 비록 논리적으로는 우리가 JMS 서비스, 데이터-접근 서비스 처럼 나누어 생각할 수 있지만 같은 코드베이스에 위치하며 하나의 단위로 배포 됩니다.

개발자가 다중 모듈 프로젝트로 만들었다고 할지라도 하나의 모듈이 다른 모듈에 의존적이며 게다가 의존성이 있는 모듈은 같은 클래스 경로에 위치해야 합니다. 비록 분산 환경을 사용하고 있다하더라도 프로그램은 단일 프로세스 컨텍스트 아래에서 동작합니다.

따라서 다른 서비스들이 단일 프로세스 안에서 서로 커뮤니케이션을 합니다. 원활한 커뮤니케이션을 위해서는 모든 아티팩트(artifiact)와 필요한 라이브러리가 각각의 응용프로그램 컨테이너에 들어있어야 합니다.

JMS 서비스가 데이터 접근 계층을 사용하기 원한다고 가정해 봅시다. JMS 컨테이너는 데이터 접근 계층의 jar과 데이터 접근 계층이 의존하고 있는 jar들(2단계 의존성)이 모두 필요합니다.

계념적으로 많은 애로사항(pain points)이 존재하며 사실상 아키텍처측면에서 매우 융통성이 없습니다.

모놀리스 방식의 스프트웨어를 개발할 때 직면할 수 있는 몇 가지 문제점들을 나열해 보겠습니다.

문제점 1

하나의 코드베이스인체로 코드가 점차적으로 증가합니다. UI 개발자, 비즈니스 계층 개발자를 불문하고 모든 개발자는 같은 코드 베이스 내에서 커밋을 하며 코드를 관리하는 것이 매우 비효율적이 되어버립니다. 개발자가 오직 JMS 모듈 안에서 개발을 하고 있다고 가정해봅시다. 하지만 개발자는 코드베이스 전체를 그의 로컬 컴퓨터에 받은 후 로컬 서버에서 실행할 수 있게 전체 모듈을 설정해야 합니다. 왜 그래야만 할까요? 개발자는 JMS 모듈에만 집중해야 하지만 현재 시나리오에서는 JMS 모듈에만 집중하는 것이 불가능합니다.

문제점 2

하나의 코드 베이스에서 모듈은 서로 의존적이기 때문에 한개의 모듈안에서 최소의 변경 사항도 모든 아티팩트를 생성하고  분산된 각 서버풀에 배포 해야합니다.

JMS 모듈과 비즈니스 모듈이 데이터 접근 모듈에 의존성이 있는 멀티-모듈 프로젝트가 있다고 가정해봅시다. 데이터 접근 모듈의 간단한 변경사항 하나도 개발자가 JMS모듈과 비즈니스 모듈을 재패키지하고 서버풀에 배포해야합니다.

문제점 3

세 개의 다기능 팀이 3계층 아키텍처를 사용하는 모놀리스 방식의 소프트웨어에 추가 될 한 가지 기능 개발에 참여하고 있습니다. 비록 3계층 아키텍처가 책임의 분리를 제공함에도 불구하고 장기적인 관점에서는 경계는 서로 겹치게되고 계층은 유연함을 잃고 경직되게 됩니다.

재고 관리 기능이 개발되었다고 가정해봅시다. UI, 비즈니스 계층, 데이터 접근 계층은 각자 맡은 일이 있습니다. 하지만 모든 계층에서 자신의 주 업무 부분을 제어하길 원합니다. 다시 말하면 결함이 발생하는 경우 맡은 각자의 계층에서 다른 계층의 개발자에 의존하지않고  문제를 해결할 수 있기를 원합니다. 이러한 경쟁 때문에 경계는 끝내 서로 겹치게되며 결과적으로 비효율적인 아키텍처가 됩니다.

문제점 4

많은 프로젝트에서 필자는 개발팀과 다른 여러 지원팀으로 나뉘어 있는것을 보았습니다. 개발팀은 오직 프로젝트 개발하고 프로젝트 출시 이후에는 지원팀에 프로젝트를 인계합니다. 개인적으로 이러한 문화에 찬성하지 않습니다. 비록 약간의 지식은 인계하는 동안에 전달되겠지만 그것만으로는 문제를 해결하기에는 부족합니다. 심각한 문제의 경우 지원팀은 개발팀으로부터 도움을 받아야 하며 이는 지원팀의 신용에 상처를 나게합니다.

문제점 5

시스템이 모놀리스 구조이기 때문에 팀 관리 또한 모놀리스 구조가 됩니다. 보통 계층을 기반으로 UI 개발자, 백엔드 개발자, 데이터베이스 프로그래머, 등으로 팀을 구성합니다. 팀 멤버들은 해당 도매인 내에서는 전문가이지만 다른 계층에 관해서는 약간의 지식만을 가지고 있습니다. 심각한 문제가 발생했을때 (자신이 맡은)각 계층을 둘러싸고 비난 게임이 시작됩니다. 비단 그뿐만 아니라 어떤 계층에 문제가 있는지와 누가 해당 문제를 해결해야 하는지를 결정하기 위한 추가적인 시간이 들어가게 됩니다.

넷플릭스와 아마존은 이러한 문제들을 위해 해결책으로 마이크로서비스를 언급합니다.

마이크로서비스 아키텍처는 다른 서비스에 의존성이 없고 배포와 관리를 단독으로 할 수 있는 수준에서 제품 또는 프로젝트를 독립적인 서비스로 나누라고 이야기합니다.

이 정의를 보고난 후에 분명이 마음속에 드는 질문이 하나 있을겁니다. 어떤 기준으로 프로젝트를 독립적인 서비스로 나누어야 할까요?

많은 사람들이 마이크로서비스에 대한 잘못된 생각을 가지고 있습니다. 마이크로서비스는 여러분의 프로젝트를 JMS, UI, 로깅, 기타처럼 계층을 기반으로 프로젝트를 나누라고 말하지 않습니다.

아닙니다. 분명하게 계층기반으로 나누라고 말하지 않습니다. 기능을 기반으로 프로젝트를 나누어야 합니다.

기능은 나누어질수 없으며 다른 기능에 의존성이 없어야 합니다.

따라서 프로젝트가 만약 재고, 주문, 결재, 배송 그리고 장바구니 UI 모듈을 가지고 있다면, 우리는 각 서비스를 독립적으로 배포가능한 모듈로 나눌수 있습니다. 각 서비스는 각자의 관리, 모니터링, 어플리케이션 서버, 데이터베이스를 가지고 있습니다. 그래서 마이크로 서비스를 사용하면 중앙화된 데이터 베이스가 없습니다 - 각 모듈이 자신의 데이터베이스를 가자기고 있습니다.

그리고 데이터 베이스는 관계형 또는 NoSQL 데이터베이스일 수 있습니다. 여러분의 모듈에 따라 선택하면 됩니다. 선택에 따라 폴리글랏 퍼시스턴스가 생성됩니다.

마이크로서비스 문화의 가장 중요한 특성은 서비스를 개발한 사람이 누구든지간에 서비스 관리는 팀의 책임이라는 것입니다. 이 특성은 인계라는 개념을 없애고 인계와 연관된 문제들을 방지합니다.

마이크로서비스의 장점과 단점

1

2

장점 1

단일체 소프트웨어에서는 코드 저장소로써 개발자는 오직 하나의 언어(예를들면 자바)로 개발합니다. 하지만 마이크로서비스에서는 각 서비스는 독립적이고 새로운 프로젝트이며 요구사항에 맞는 어떠한 언어든지 사용해서 개발될 수 있습니다.

장점 2

개발자는 오직 특정 서비스만 집중하기 때문에 코드 저장소는 매우 작을 것이고 개발자는 코드를 잘 알고 있을 것입니다.

장점 3

서비스가 다른 서비스와 통신할 필요가 있을때 API를 통해(구체적으로 REST 서비스에 의해) 서비스들은 통신할 수 있습니다. REST 서비스는 커뮤니키에션을 위한 중개자이기 때문에 매우 작은 변환만 있습니다. SOA와는 다르게 마이크로 서비스 메시지 버스는 아주 많은 변환, 분류, 라우팅을 하는 ESB보다 훨씬 더 얇습니다.

장점 4

중앙화된 데이터베이스가 없습니다. 각 모듈은 각자의 데이터베이스를 가지고 있기 때문에 데이터는 분산 되어있습니다. 개발자는 모듈에 따라 NoSQL 또는 관계형 데이터베이스를 사용할 수 있다는 사실은 전에 언급한 폴리글랏 퍼시스턴스를 데뷔시킵니다.

많은 사람들이 SOA와 마이크로서비스가 같은것이라고 생각합니다. 정의에 따르면 같아 보이지만 SOA는 데이터를 관리하고 분류하는 등 많은 책임을 가진 ESB를 통해 서로 다른 시스템간에 통신을 위해 사용되었습니다.

하지만 마이크로서비스는 입력을 한 서비스에서 다른 서비스로 전송만하는 단순 메시지 버스(dumb message bus)를 사용하지만 메시지를 받는 엔드포인트(endpoint)는 전에 언급한 작업들을 할 수 있을 정도로 똑똑합니다. 마이크로서비스는 우둔한 메시지 버스를 가지고 있지만 똑똑한 엔드포인트가 있습니다.

마이크로 서비스는 REST를 통해 통신을 하며 변환 범위는 API를 통해 호출하는 다른 서비스에 의존하는 오직 하나의 서비스로 아주 작습니다.

하지만 마이크로서비스 또한 단점을 가지고 있습니다.

모든 기능적 특성은 개별 서비스이며 따라서 큰 프로젝트에는 많은 서비스들이 있습니다. 이러한 서비스들을 모니터링하는 것은 오버헤드를 증가시킵니다.

그뿐만이 아니라 서비스가 장애가 나는 경우 장애를 추적하는 것은 힘든 작업이 될 수 있습니다.

서비스는 다른 서비스를 호출하기 때문에 경로를 추적하고 디버깅하는 것 또한 어렵습니다.

각 서비스는 로그를 생성하기 때문에 중앙 로그 모니터링은 없습니다. 이는 매우 고통스러운 부분이며 장애를 대비해 아주 좋은 로그 관리 시스템을 필요로 합니다.

마이크로서비스에서는 각 서비스는 모놀리스 소프트웨어의 프로세스간 통신에 비해 좀 더 큰 오버헤드를 가진 API/원격 호출을 통해 통신합니다.

이러한 모든 결점에도 불구하고 마이크로서비스는 실제로 책임의 분리를 이뤄냅니다.

결론

지금까지 DZone에 게시된 글에 대해 정리해 보았습니다. 개인적으로는 마이크로 서비스 아키텍처는 이미 기존 서비스 운영을 잘하고 있고, 장애 처리나 모니터링 등을 잘하고 있는 조직이 다음 단계로 진화하는 아키텍처로 선정하는 것이 좋다고 생각합니다. 처음부터 마이크로서비스 아키텍처를 선택하면 운영 및 관리의 헬에서 빠져 나오기 어렵고 그런 오버헤드가 마이크로서비스 아키텍처의 장점을 상쇄시킬 정도로 충분히 클 가능성이 높기 때문입니다. 그리고 초기 단일체 구조 아키텍처로 시작된 작은 서비스가 서비스가 복잡해지고, 조직도 커지고, 팀원의 역량은 충분히 높아졌으면 마이크로서비스 아키텍처로의 진화를 고려하는 것이 좋을 것 같습니다.


Popit은 페이스북 댓글만 사용하고 있습니다. 페이스북 로그인 후 글을 보시면 댓글이 나타납니다.