마이크로서비스의 필요조건들

Updated:

마이크로서비스의 필요조건들

마이크로서비스를 위한 조건은 무엇인가?

그럼 마틴 파울러가 언급한 MSA의 주요 특징을 좀더 살펴보자. 특히 이 특징들은 마이크로서비스를 잘 구현하고 있는 조직들의 사례이며 동시에 마이크로서비스 구현을 위한 필요 조건이 된다. 이러한 시각은 MSA의 성공이 CBD, SOA처럼 기술만으로 생각하여 아키텍처스타일 추구에 그치지 않고 하나의 개발 환경,문화,일하는 방식과도 연계되어 있음을 보여준다.

조직의 변화 : 업무 기능 중심 팀

콘웨이 법칙이라고 멜빈 콘웨이가 정의한 조직과 조직이 개발한 소프트웨어의 관계를 정의한 법칙이 있다. 쉽게 설명하면 시스템 개발 시 항상 시스템의 모양이 팀의 구조를 반영하는 것을 말한다.

아래 그림과 같이 예전의 일하는 방식을 보면 하나의 애플리케이션을 만드는 데 UI팀, 프론트 엔드 개발팀, 백엔드개발팀, DB팀과 같은 직능적으로 같은 기술을 가진 서로 다른 팀들이 존재하고 하나의 어플리케이션을 만드는데 이 팀에서 각각의 인원이 참가하여 프로젝트를 만들어서 관여하였다.

따라서 시스템도 그 같은 모양이 되고 이런 방식의 팀 구조에서 일할 시는 아무래도 팀이 다르다 보니 의사소통시간이 오래 걸렸고 의사결정도 느리게 된다.

기술 별 분리된 팀과 팀이 만들어내는 시스템

그렇다면 현재의 마이크로서비스팀의 구조는 어떻게 되야 할까? 마이크로서비스를 만드는 팀은 업무 기능 중심 팀이 되어야 한다. 업무 기능 중심 팀은 역할 또는 기술 별로 팀이 별도 존재하는 것이 아니라 업무 중심으로 기술이 다양한 사람들이 동일한 팀이 되어 서비스를 만드는 것을 의미한다.

이런 업무 기능 중심 팀은 아래 그림과 같이 다양한 역할(기획자, 디자이너, Frontend 개발자, Backend 개발자, 설계자, 테스터 등)으로 구성되고 이 팀은 서비스를 처음부터 끝까지 만들기 위한 모든 역할을 갖추고 있다. 또한 같은 공간, 같은 시간을 공유하는 팀이므로 의사소통도 원활하고 의사결정도 빠르게 진행될 수가 있다.

이 팀을 여러 기능들이 모여 있다는 의미에서 다기능 팀(cross-functional team) 이라고도 부른다. 이 팀은 자율적으로 해당 비지니스에 관련된 서비스를 만들 뿐만 아니라 개발 이후에 운영할 책임까지 진다.

아마존닷컴은 이런 팀을 two pizza team이라고 말하는데 이는 피자 두 판으로 서로 빈번히 의사소통하며 같이 식사할 수 있는 정도의 팀원 숫자를 의미하며 여러 역할자를 가진 개발과 운영을 책임지는 팀이다.

업무 중심 다기능 팀

이러한 팀은 마이크로서비스를 만드는 데 필요한 기술을 팀 내부에 모두 가지고 있으므로 그 외 마이크로서비스 팀과는 협력할 일이 작을 수 밖에 없다. 따라서 콘웨이 법칙에 의해 아래 그림과 같이 이 팀이 만든 마이크로서비스도 그 외 팀의 마이크로서비스와는 느슨한 연계를 가지게 된다.

업무 중심 팀과 팀이 만들어 낸 느슨한 연관관계를 갖는 마이크로서비스

관리체계의 변화 : 자율적인 분권 거버넌스 폴리그럿(Polyglot)

앞서 아마존에서는 다기능 팀이 개발과 운영을 책임진다고 하는데 아마존에서는 이런 조직문화를 “built in, run it” 이라는 모토로 표현한다.

간단이 의역하면 “우리가 만들고 우리가 직접 운영한다”라는 의미이다. 마이크로서비스를 만드는 조직은 중앙의 강력한 거버넌스를 추구하지 않는다 .따라서 마이크로서비스 팀으로 구성된 조직은 중앙의 강력한 표준이나 절차의 준수를 강요하지 않는다.

각 마이크로서비스 팀은 빠르게 서비스를 만드는 것을 목적으로 스스로 효율적인 방법론과 도구, 기술을 찾아 적용한다. 아마도 현실 세계에 작은 정부, 지방자치제도와 유사할 것 같다.

아래 그림은 각 마이크로서비스팀이 자신의 서비스 성격에 맞는 최적의 언어와 저장소를 자율적으로 선택함을 보여준다. 상품서비스팀은 상품검색서비스를 위해 빠른 검색에 특화된 NoSQL 몽고DB와 Node.js언어를 선택했고 계약서비스팀은 계약서비스를 위해 자바 언어와 오라클 DB를 선택하였다

자율적인 거버넌스 체계

개발생명주기의 변화 : 프로젝트가 아니라 제품 중심으로

기존까지 대부분의 어플리케이션 개발 모델은 프로젝트 단위였다. 그래서 필요한 기술의 인력들이 한시적으로 모여 장기간의 프로젝트를 통해 오랫동안 개발하고 이를 운영 조직에 넘기는 방식이다. 개발 조직과 운영 조직이 분리되어 있었다. 또한 명확한 계획을 세우고 개발 기능을 나열하고 개발에 대한 데드라인이 있어 그 일정에 맞추어 정확히 기능을 제공해야한다.

따라서 기간 중에 발생한 변경이나 새로운 아이디어를 포용하지 못했다. 그러나 마이크로서비스팀의 개발은 비지니스의 갑작스런 변화에 유연하게 대처해야 하고 개발뿐만 아니라 운영을 포함한 소프트웨어의 전체 라이프사이클을 책임져야 한다.

따라서 소프트웨어를 완성해야 할 기능들의 세트로 보는 게 아니라 제품으로 바라보고 우선 개발한 뒤에 반응을 보고 개선하는 방식으로 소프트웨어를 개발한다.

즉 소프트웨어 개발방시에 있어 프로젝트 형태의 폭포수 모델, 빅뱅 방식으로 개발하는 것이 아니라 점진 반복적인 모델, 제품(Product) 중심의 Agile 개발 방식 으로 개발한다. 이런 방식은 약 2~3주의 iteration이나 스프린트를 통해 소프트웨어를 개발, 배포하여 바로 피드백을 받고 반영할 수 있게 해준다.

또 이런 방식은 소프트웨어를 프로젝트를 통해 고객의 고정된 요건을 받아 어떠한 시점에 완성된다는 개념으로 보지 않고 요건의 변경에 따라 지속적으로 개선되고 발전해 시킬 프로젝트로 바라본다. 아래 그림의 왼쪽은 기존의 고정된 요건을 단계별 프로젝트 중심의 생명 주기로 구현하는 모습을 그리고 오른쪽은 요건의 변경에 따라 지속적으로 개선되는 프로젝트 중심의 소프트웨어 개발 생명 주기를 보여준다.

마이크로서비스 개발 주기

개발 환경의 변화 : 인프라 자동화

마이크로서비스는 독립적으로 배포된다. 모노리스처럼 한 덩어리로 배포한다면 수동 방식도 크게 문제가 없겠지만 마이크로서비스처럼 여러 개로 쪼개진 상태에서는 수동 방식은 좋은 선택이 아니다. 따라서 여러 개의 마이크로서비스를 빠르게 배포하기 위한 방법이 필요하다.

마이크로서비스가 화려하게 등장한 이유는 클라우드라는 가상 인프라 발전에 기인한다. 아래 그림과 같이 전체 소프트웨어 구현 과정은 개발환경을 준비하는 과정, 실제로 소프트웨어를 개발하는 과정, 개발 완료된 소프트웨어를 빌드, 테스트, 배포하는 개발지원과정으로 구분된다. 첫 단계인 개발환경준비과정에 개발환경을 클라우드 인프라로 쉽고 빠르게 준비 할 수 있어서 팀의 개발속도가 높아 졌다.

그렇다면 개발이 완료된 후에 필요한 빌드,테스트,배포의 개발지원과정 속도는 어떻게 높일 수 있을까? 당연히 이러한 개발지원 활동도 팀의 속도와 품질에 많은 영향을 미치므로 쉽고 빠르게 사용할 수 있으면 좋다.

가장 좋은 방법은 자동화이다. 이런 개발 지원 환경 자동화에는 소스코드를 build하는 도구와 build하며 테스트하는 도구 그리고 가상화된 인프라에 배포하는 도구들이 모두 필요하다. 마이크로서비스 팀이 단기간에 제품을 빨리 개발, 피드백 받기 위해 이러한 개발 지원 환경 자동화가 반드시 갖춰져야 한다. 이런 환경은 개발과 운영을 동시 수행하는 DevOps(데브옵스)를 궁극적으로 가능하게 하므로 속칭으로 데브옵스 개발 환경이라 부르기도 한다. 개발환경, 개발지원환경 자동화를 모두 통틀어 인프라 자동화라고 하기도 한다. 인프라 자동화는 마이크로서비스 개발과정의 필수조건이 되야 한다.

다음 그림은 이러한 과정을 묘사한 배포파이프라인 이다. 빌드 → 개발환경배포→ 스테이징환경배포→ 운영 환경에 배포로 구성된다. 이 배포 파이프라인 프로세스를 자동화 도구를 활용하여 자동화 해야 한다. 또한 최근에는 이런 배포 환경이 마이크로서비스 갯수에 따라 급격하게 늘어나기 때문에 이를 효율적으로 관리하기 위해 인프라 구성과 자동화 을 마치 소프트웨어 처럼 코드로 처리하기 위한 방식인 ‘Infrastructure as code’가 주요 키워드가 되고 있다.

배포 파이프 라인의 자동화

저장소의 변화 : 통합 저장소가 아닌 분권 데이터 관리

예전 모노리식 시스템을 살펴보면 단일 통합 데이터베이스를 사용하고 있다. 이러한 단일 데이터베이스를 유지하는 방식은 과거 스토리지 가격 및 네트워크 속도에 따른 데이터의 안정성과 효율성 추구의 소산이다. 따라서 데이터의 정규화가 반드시 추구해야 할 가치였다. 그러나 현재의 스토리지 가격은 싸고 네트워크 대역폭은 매우 커졌다.

데이터를 억지로 꾸깃꾸깃 작은 공간에 넣을 필요가 없다. 마이크로서비스는 폴리그랏 저장소(Polyglot Persistence) 접근 방법을 선택하며 서비스 별로 데이터베이스를 갖도록 설계한다. 즉, 이는 각각의 저장소가 분산되어 있어야 하며 다른 서비스의 저장소를 직접 호출할 수가 없고 API를 통해서만 접근해야 함을 의미한다.

이런 구조에서는 일부 데이터의 중복과 복제를 허용함이 효율적이다. 그런데 이런 경우에 반드시 등장하는 문제가 있다. 각 마이크로서비스의 저장소의 데이터의 비즈니스 정합성을 맞추는 데이터 일관성 문제이다.

이러한 경우에 데이터 일관성을 유지하기 위해 보통 데이터일관성 처리를 위해 분산 트랜잭션을 사용하는데, 각각 다른 서비스를 하나의 트랜잭션으로 묶다 보면 각 서비스의 독립성도 침해 받고 NO-SQL 저장소처럼 분산 트랜잭션을 지원하지 않는 경우도 있다.

따라서 마이크로서비스는 이런 경우 두 서비스 간의 단일 트랜잭션이 아닌 이벤트 처리를 통한 협업을 강조한다. 이 말은 결과적 일관성(Eventual Transaction) 이라고도 표현하기도 하는데 두 서비스의 데이터가 일시적으로 불일치하는 시점에 있고 일관성이 없는 상태이지만 결국에는 두 데이터가 같아진다는 개념이다. 즉 트랜잭션을 하나로 묶지 않고 별도의 로컬 트랜잭션을 각각 수행하고 일관성이 달라진 부분은 체크하여 보상트랜잭션으로 그 일관성을 맞춰주는 개념이다.

아래 그림을 보면 주문서비스와 배송서비스가 있고 각각의 저장소가 분리되어 있다. 주문이 되면 반드시 배송 처리가 되어야 하는 비지니스가 있다고 생각해 보자. 두개의 업무를 분산 트랜잭션 하나로 묶으면 배송서비스 실패 시 바로 주문 서비스 롤백을 처리할 수 있을 것이다.

그렇지만 하나의 데이터 저장소가 분산트랜잭션을 지원하지 않는 저장소라고 하면 이는 불가능 할 것이다. 또한 분산 트랜잭션으로 묶는다면 두 서비스가 강하게 결합되어 있어 서비스를 분리한 효과를 누리기 힘들 것이다. 마이크로서비스가 추구하는 다른 방법은 각 트랜잭션을 분리하고 큐 메커니즘을 이용해 보상트랜잭션을 활용하는 방법이다.

다음과 같이 처리하여 비지니스 일관성을 맞출 수 있다.

  1. 주문 서비스가 주문처리 트랜잭션을 수행한다.
    a. 동시에 주문 이벤트 발행한다.
    b. 주문 이벤트가 메시지 큐로 전송된다.
    c. 배송 서비스가 주문 이벤트를 인식한다.

  2. 배송서비스가 주문 처리에 맞는 배송처리 트랜잭션을 수행한다. (비지니스 일관성 만족)

  3. 배송서비스처리 트랜잭션 중 오류로 트랜잭션을 실패한다.
    a. 배송처리실패이벤트 발행
    b. 배송처리 실패 이벤트가 메시지 큐로 전송된다.
    c. 주문 서비스가 배송처리 실패 이벤트를 인식한다.

  4. 주문서비스는 주문취소(보상트랜잭션)를 수행한다. (비지니스 일관성 만족)

협업을 통한 비지니스 일관성

실패를 고려한 설계

아마존의 부사장인 위너 보겔스가 ‘소프트웨어는 모두 실패한다’ 라는 말을 했다. 마이크로서비스는 언제든 실패할 수 있으며 실패해서 더 이상 진행할 수 없을 때도 자연스럽게 대응할 수 있도록 설계해야 한다는 말이다. 이러한 성격을 내결함성(Fault tolerance)이라 한다.

예전의 시스템의 아키텍처는 결함이나 실패 무결성을 추구 했다. 다운되지 않고 무중단되지 않기 위해서는 완벽을 추구해야 하며 강건 해야 했다. 그렇지만 위너 보겔스의 말처럼 실패하지 않을 수 없다. 실패하지 않는 시스템을 만드는 것보다 실패에 빠르게 대응할 수 있는 시스템을 만드는 것이 쉽고 효율적이다.

이를 위해서는 다양한 실패에 대비하여 자동으로 테스트할 수 있는 환경을 마련해야 하고 이런 마이크로서비스의 실패를 감지하고 대응하기 위해 실시간 모니터링 체계도 갖추어야 한다. 이러한 예로 서킷 브레이크 패턴 을 말할 수 있는데 서킷 브레이크 패턴은 회로 차단기처럼 각각의 서비스를 모니터링하고 있다가 하나의 서비스가 다운되거나 실패 되면 이를 호출하는 서비스의 연계를 차단하고 이에 적절한 대응을 하는 것을 말한다. 이러한 설계는 서비스가 긴급 장애 상황에 빠르고 유연하게 탄력적으로 대응할 수 있게 한다.

넷플릭스에서는 카오스 몽키라는 장애를 일부로 발생시키는 도구를 만들어 이런 탄력적인 아키텍처가 제대로 동작하는지 점검하기도 한다.

비즈니스 민첩성은 아키텍처만으로 이루어지지 않는다.

비즈니스 민첩성을 위한 3가지 혁신 요소

클라우드 환경에서 비즈니스 민첩성을 위한 시스템의 조건으로 마이크로서비스 개념과 특성을 살펴보았다. 살펴보니 오늘날의 소프트웨어의 성공적인 개발은 아키텍처만 파고든다고 되는 것은 아닌 것을 알 수 있다.

특히 마이크로서비스 기반의 시스템 구축 시 통용되는 MSA(Microservice Architecture)라는 용어를 문자 그대로 아키텍처,기술로만 생각해서는 안될 것 같다. 즉, MSA의 성공을 위해서는 아키텍처,프로세스, 조직문화 등이 모두 서로의 필요조건 및 충분조건이 되고 이것들이 모두 어우러질 수 있을 때 잘 구조화된 아키텍처도 빛을 볼 수 있을 거라 생각한다.

따라서 아래 그림과 같이 클라우드 환경에서 비즈 민첩성을 강화하기 위한 3가지 요소로 유연하고 자동화된 개발환경 기반의 마이크로서비스 아키텍처, 점진 반복적인 개발 프로세스, 자율적인 업무 기능 중심 팀과 개발문화가 필요함을 알 수 있을 것이다.

비지니스 민첩성을 위한3가지 요소