Chillog 차가운 블로그

'마이크로서비스 아키텍쳐 구축' 책읽기

책읽기 MSA 아키텍쳐

 직무를 막론하고 최근 Cloud-Native Application(CNA) 관련역량이 필수불가결해졌다. 특히 MSA가 과연 우리 조직구조와 비즈니스에 적합한 구조일까라는 궁금증도 있었고 내 머리 속에 산재되어있는 개념들을 출판된 책이 서술하고있는 형태를 빌려, 쭉 정리하면 좋겠다는 생각에 정리해봤다. 이 책의 원판 출판일은 무려 7년전인 2015년 2월으로, 벌써 트랜드가 두세번은 바뀌었을 시간이다. 제법 오래된 책이지만, MSA가 각광을 받기시작할때 쓰여지던 책이라 전통 서비스 구조(MSA와 구분 짓기 위해 MSA와 다른 모든 전통 패턴들을 Monolithic이라한다.)에 대한 문제점에 그에 대한 해결방법에 대한 서술이 충분했던 것 같다. 물론 원판출판 이후에 트랜디한 기술들이 많이나왔기에 이 점을 감안해야한다. 참고로 본 포스팅은 내 의식의 흐름을 따르기 때문에 본문 내용이 책의 목차 순서에 맞추어 정렬되어있지않다.


  • 초판: 2017년 3월 (원판: 2015년 2월)
  • 한빛미디어

개요

 이 책은 기존 통합계에서 설계해왔던 Monolithic 앱 설계기법에 대한 문제점을 나열하고, 그에 따른 MSA 필요성을 설명하며 설계 및 구축기법을 설명하고있다. 수년전, Monolithic 앱의 대항마로 분산 시스템 특히 SOA (서비스지향 아키텍쳐, Service-Oriented Architecture)는 떠오르는 키워드였다. 저자는 SOA는 훌륭한 아이디어였지만, 산업계 다수가 문제를 전체적으로 보지못하고 SOA를 잘하는 방법에 대한 합의는 부족했다며 이러한 SOA가 실패했었던 이유를 경계하고, MSA는 SOA에 대한 특정 접근법으로 봐야한다고 얘기한다. 그 때문인지 최근 SOA라는 용어는 거의 쓰이지 않는다. 그래도 책에 자주 언급되는 생소한 내용이니 SOA에 대한 특징을 간략히 정리해보고 가자.

SOA의 특징

  • 기존 Monolithic 앱에서 의미있는 서비스(기능)단위를 공통 서비스로 묶어 재사용성을 장려하는 아키텍쳐
  • 서비스(모듈)간의 의존성을 최대한 줄임으로서, 느슨한 결합을 유지
  • Biz service / Common biz service / insfrastructure service 등 서비스 별 계층 구조를 가지고있음
  • 서비스 수준의 재사용성을 추구한다는 점에서, MSA와 추구하는 가치/철학은 다르지 않음 (22.09.21. 개념이 조금 다르다..)

 아래는 책에 묘사되어있는 내용은 아니다. 간략하게 Monolithic, SOA, MSA 각 패턴별 설계 주요특징을 도식화해봤다.

 확실히 최근 MSA를 소개하는 내용들과 SOA의 주된내용이 크게 다르지않다. 그 때문인지 이 책에서는 SOA에서 MSA로 마이그레이션하는 예를 들기보다는 Monolithic에서 MSA로 마이그레이션하는 예시를 들며 설계기법을 설명해 나가고있다.

(22.09.21 추가)
 최근에 아키텍트 교육을 들으며 보고서를 오지게 쓰는 와중에, IBM 클라우드 블로그에서 SOA와 MSA에 대한 차이점을 설명해둔걸 찾았다. SOA vs. Microservices: What’s the Difference? 두 개념이 단순하게 전후관계가 있는 내용인줄 알았으나. 내가 잘못된 접근법으로 이해하고있었던 것 같다. 이 포스트(What is SOA (Service-Oriented Architecture)?))도 같이 읽으면 좋을 것 같다. 시간나는대로 별도 포스트로 한번 정리해보겠다.

은탄환은 없다. 아키텍트의 역할
 어떤 설계패턴이든 ‘은탄환’이 되는 설계는 없다. 각각을 재단하듯이 설명하려고 하지않는게 당연하다고 생각한다. 저자도 이를 중요시하며, 아키텍트의 역할에 대해 견고히 제시하고, 아키텍트는 ‘진화적 아키텍트’가 되어야한다고 강조한다.

  • 비전: 명료하게 소통되고, 시스템이 고객과 조직의 요구 사항을 충족하도록 돕는 기술 비전이 있는지 확인하라.
  • 공감: 고객과 동료에 대한 여러분 결정의 파급력을 이해하라
  • 협업: 비전을 정의하고, 다듬고, 실행하기 위해 가능한 한 많은 동료와 협업하라.
  • 적응성: 기술 비전이 고객과 조직이 요구하는 것을 반영하는지 확인하라.
  • 자율성: 여러분 팀의 표준화와 자율성 사이에서 올바른 균형을 찾아내라.
  • 거버넌스: 시스템이 기술 비전에 맞게 구현되고 있는지 확인하라.

아키텍트는 많은 것에 대해 책임을 진다. 그들은 개발을 이끌 수 잇는 일련의 원칙을 정하고, 원칙들이 조직의 전략과 일치하도록 보장할 뿐만 아니라 이 원칙들로 인해 개발자를 비참하게 만드는 실천 사항이 만들어지지 않도록 해야한다. 최신 기술을 유지하고, 올바른 트레이드오프를 결정해야한다. 이는 실로 엄청난 책임이다. 그뿐 아니라 아키텍트는 사람들과 함께 나아가야한다.

(중략)

거대한 모놀리식 시스템에서는 사람들이 성장하고 무엇인가를 소유할 기회가 거의 없다. 반면 MSA에서 우리는 독립적 수명주기를 가진 수많은 자율적인 코드베이스를 지닌다. 사람들이 더 많은 책무를 맡기 전에 개별 서비스의 소유권을 부여함으로써 그들을 성장시키는 것은 그들 자신의 경력 목표를 성취하도록 돕는 훌륭한 방법일 뿐만 아니라 다른 담당자들의 짐도 덜어준다.

 아키텍트가 아닐지라도, 시스템 구성원으로서도 고민해볼만한 문제다. 특히 저자는 조직구성과 아키텍트에 대한 상관관계에 대한 서술을 많이하는데 바로 콘웨이의 법칙(Conyway’s Law)이다.


콘웨이 법칙(Conway’s Law)

그 어떤 조직도 시스템(정보시스텀만이 아닌 좀 더 포괄전인 의미의 시스템)을 설계할 때 필연적으로 그 조직의 커뮤니케이션 구조를 모방하여 만든다.
Any organization that designs a system (defined more broadly here than just information systems) will inevitably produce a design whose structure is a copy of the organization’s communication structure.

 맬빈 콘웨이의 논문 「위원회가 고안하는 방식(Melvin Conwa, “How Do Commitees Invent”, 1984)」 의 주제이다. 저자는 이 법칙에 대한 재현을 아주 다양한 상황에서 목격했기에 이 법칙이 옳다고 믿는다고 한다. 콘웨이의 법칙은 실제로도 많이 인용되었으며 많은 후속연구가 진행되었다. 저자의 경험과 사례들로 미루어 봤을때 조직구조가 시스템과 시스템의 본질에 큰 영향을 준다는 것을 보여준다고 주장한다.

넷플릭스와 아마존
 최근 업계에 있었다면 한번은 들어봤을법한 사례다. ‘팀의 규모가 피자 두판으로 식사를 마칠 수 없는 규모가 돼서는 안된다’는 아마존의 피자 두 판 크기의 팀 법칙은 유명하다.

담당 서비스의 전체 수명주기를 소유하는 작은팀의 추구는 아마존이 AWS를 만들 수 있었던 일등 공신이다. 그리고 아마존은 각 팀이 자립하는 데 필요한 도구들을 만들어야 했다.
넷플릭스는 아마존의 사례를 교훈삼아 처음부터 작고 독립적인 팀을 조직했고 그 결과 독립적인 서비스를 만들 수 있었다. 이를 통해 변경 속도에 최적화된 시스템 아키텍처를 확보할 수 있었다.


고려요소들

  • 의사소통 비용: 지리적으로 분산된 팀의 의사소통 비용이 높을수록 변경을 조율하는 비용 또한 높아짐.
  • 서비스 소유권: 앱의 배포와 유지보수까지 한 팀이 책임지게 하면 그 보상으로 배포하기 쉬운 서비스가 만들어짐.
  • 공유 서비스는 차선책: 공유서비스는 차선책 모델이지만, 왜 공유서비스 구조를 가지는 이해하고 있어야함. 만약 공유서비스를 없앨 수 없다면 내부 오픈 소스로 관리. 단, 오픈소스 관리정책을 차용하여 관리할 것(신뢰/비신뢰 커미터, 관리자 등…).
  • 경계가 있는 컨텍스트

콘웨이의 법칙은 시스템을 조직 구조와 다르게 설계할 때의 위험을 강조한다. 이 법칙은 서비스의 소유권을 동일 위치의 팀과 나란히 정렬시킬 수 있도록 해준다. 그리고 그 팀은 스스로 조직의 경계와 동일한 경계가 있는 콘텍스트 주위로 정렬된다. 이 둘이 나란히 배치되지 않는다면 이 장에서 설명한 많은 불안 요소가 발생 할 것이다. 우리는 서비스 소유권과 조직 간의 관계를 이해함으로써 구축할 시스템과 조직이 부합되도록 해야 할 것이다.


모델링 (Modeling)

 저자는 모델링에 있어, 다음 두 가지 개념을 강조하는데, 이는 흡사 객체지향프로그래밍의 SOLID 원칙과 닮았다. 클래스(객체)를 잘 나눠야 하듯이, 서비스를 나누는 ‘경계’를 잘 나눠야함을 강조한다.

  • 느슨한 결합: 서비스가 느슨히 결합되어있으면 하나의 서비스가 변경될 때 다른 서비스가 변경되는 일이 없다.
  • 강한 응집력: 서로 연관된 행위가 한 곳에 모이고, 다른 경계와는 가능한 한 느슨하게 소통할 수 있도록 한다.

 다시 강조하지만, 위 두 개념은 결국 ‘경계’를 잘 나누는데에서 시작한다. ‘경계’를 나눈다는 것은 서비스 도메인을 잘 이해하고있다는 바탕에서 이루워져야한다는 것을 얘기한다. 그 개념을 설명하는 것이 ‘경계가있는 컨텍스트(Bounded Context)’ 이다.

 경계가 있는 컨텍스트(Bounded Context) 는 도메인 주도 설계(Domain-Driven Desgin)에서 나온 개념으로서, 특정 모델에 대해 경계가 정해진 적용 가능성을 얘기한다. 명료한 경계에 의해 강제된 구체적인 책임, 2012

서비스 경계를 잘못 정하면 큰 비용이 들게 되므로 새로운 도메인 영역에 익숙해져서 안정화될 때까지 기다리는 것이 현명하다.

(중략)

결국 서비스 경계에 대한 초기 견해가 옳지 않았음이 명백해졌다. 이것은 서비스 간의 수많은 변경과 그에 따른 높은 비용 소모를 초래했고 결국 팀은 서비스를 다시 단기간에 경계를 구분 할 수 있는 단일 모놀리식 시스템으로 합쳤다. 그로부터 1년 뒤, 해당 모놀리식 시스템을 훨씬 안정적인 경계를 가진 마이크로서비스로 분리할 수 있었다.

(중략)

여러모로 기존 코드베이스를 마이크로서비스로 분해하는 것이 처음부터 마이크로서비스로 가는 것 보다 훨씬 쉽다.

 잘못된 경계로인한 성급한 분해를 경계해야한다. MSA를 소개 및 언급하는 여타 많은 포스팅에서도 ‘처음부터 MSA로 짜지말고 Monolithic으로 설계한 뒤 서비스 규모가 커지면 MSA로 설계하라‘고 언급했었던 것을 본 것 같다. 이 책에서도 같은 의견을 게재하며, Monolithic 앱에서 MSA로 전환하는 방법을 소개하는 내용을 위주로 책 내용을 풀어나가고있다. 이렇게 하는 모든 이유는 도메인에 대한 이해가 선행되어야하기 때문이며 그에 따른 경계 설정이 중요하다. 이렇게 경계가 설정된 콘텍스트들은 접합부를 찾는 데 중요한 도구고, MSA를 이 경계에 정렬하여 우리의 최종 시스템이 온전한 장점들을 유지하도록 만들어야 한다.


통합 (Integration)

 MSA 통합에 있어 궁극적으로 추구하는 것이 무엇이며, 이상적인 통합이 어떤 것일지 생각해봐야한다. (말그대로 이상적인 내용이다. 간단하게 정리하고 넘어간다)

  • 호환성을 깨뜨리는 변경 피하기
  • 기술 중립적인 API
  • 내부 구현 상세 감추기
  • 서비스 단순화

 고민해야되는 부분들을 다음과 같이 소개하고있다.

  • 공유DB통합 피하기: 외내부 결합되는 것을 허용하기에 테스트가 쉽지 않다. / 강한 응집력과 느슨한 결합력을 잃는다.
  • 동기/비동기: 웬만하면 비동기로 짜게됨.
    • 동기: 작업이 언제 완료되었는지 알기쉽기때문에 추론이 쉽지만, 원격서버에 대한 호출이 완료될 때까지 연산 작업이 중단됨.
    • 비동기: 호출자는 작업이 완료되었다는 회신을 기다리지않는다. 때문에 중단된 호출이 성능 저하를 일으키는 곳에서 짧은 지연시간이 필요할때 적합하다.
    • 비동기 이벤트 기반: 결합도가 매우 낮은 방식으로서, 이벤트를 발산하는 클라이언트가 이벤트에 반응하는 대상을 알지 못한채로 이벤트를 발산한다.
  • 오케스트레이션 / 코레오그래피: 오케스트레이션 보단 코레오그래피
    • 오케스트레이션(orchestration): 중앙에 의존하는 방식 / 고객 서비스에 지나치게 많은 중앙관리 권한이 부여됨 / 높은 변경 비용을 수반함.
    • 코레오그래피(choreography): 시스템의 각 부분에 작업 내용을 알리고 세부 사항을 수행하게 하는 방식 / 이벤트만을 발산함으로써 느슨한 결합을 이끌어 냄. / 단, 모니터링을 할 수 있는 환경을 추가하는 작업이 필요함.
  • RPC or REST? 통신방식에 대한 고민
     낮은 레이턴시가 필요한 서비스가 아니고선 웬만한건 REST로 설계한다는 뉘앙스로 서술하고있다. 다만 gRPC의 릴리즈가 2016.08이니, 릴리즈 이전에 퍼블리싱된 이 책의 원판에서는 gRPC 언급은 없다. 우선 이 포스트에서는 책이 언급하는 내용을 정리하고, 후속 포스트에서 gRPC에 대한 내용을 정리하며 공부해봐야겠다.
    1. 원격 프로시저 호출(Remote Procedure Call)
      쓰기쉬움 / 하지만 클라-서버간 기술결합을 초래해 사용될 기술을 제한하기도함 / 개발자가 인지를 못하고 서비스 경계를 넘어서 호출 할 수 도 있음 / 네트워크의 나쁜 신뢰성을 고려하여 회복력에 대한 고찰이 필요함 / 그럼에도 불구하고 RPC가 형편없다고 단정 짓기는 어려움.
      그래도 써야한다면: 네트워크가 완전히 은폐될 정도로 원격 호출을 추상화하지 말것 / 서버와 보조를 맞춘 클라이언트의 업그레이드 없이도 서버 인터페이스를 발전시킬 수 있는지 확인 할 것.
    2. REST
      JSON, XML … etc 많이들 사용 / 가끔은 RPC가 나은 경우가 있음 (낮은 지연시간이 필요한 통신) / 인기 많아서 괜찮은 프레임워크가 많음 / 물론 지나친 편의를 주의하며 사용할것(사용자에게 보여주지말아야할 DB내용을 고대로 deerialize해서 외부로 노출 시킨다던지..)
  • 비동기 이벤트 기반의 협업 구현
     EDM(Event Driven Microservice)이나 Event Bus를 언급하지는 않지만, 비슷한 내용이 언급되는 듯 하다. 사실 EDM 혹은 EDA 등등 역시 2015년에 들어서야 떠오르던 키워드라, 책에는 관련된 개념을 언급하는 내용이 없지않을까 싶다. EDM 관련된 내용은 역시 후속 포스트로 정리하며 공부해야겠다. 책에서는 다음 두 가지 내용을 소개하고있다.
    1. 미들웨어에 메세지 중개자를 추가하여 처리하는 방법
      RabbitMQ를 활용하여 구성하는 방법을 소개했다. 최근에는 아파치 Kafka 역시 많이 사용한다.
    2. HTTP 기반 프로토콜인 ATOM을 활용하여 이벤트 기반 설계하는 방법
      ATOM은 Atom Syndication Format과 Atom Publishcation Protocol을 지칭한다. RSS(Real Simple Syndication)와 함께 언급되는 것 같은데, Rich Site Summary로 잘 알려진 그것이다. RSS 포멧의 단점을 극복하기위하여 설계되었다고한다.
  • 반응형 확장 (Reactive eXtenstions) / 반응형 프로그래밍 (Rx Programming)
     Rx는 다수의 호출 결과를 조합하고 그 결과에 따라 연산을 실행하는 메커니즘임. / Rx는 관찰자(Observer) 패턴에 기반을 두고 설계됨 / 관찰 대상 순서를 이용하여 비동기 이벤트 기반의 반응형 프로그램을 지원하는 라이브러리임. / 함수형 프로그래밍 라이브러리의 일종이다. / 다음은 RxJava 를 설명한 포스트인데, Rx와 Rx 라이브러리의 개괄적인 부분들이 잘 설명해주셨다.

  • 함수형 프로그래밍
     input 값을 바꾸지않은 채, output값을 새로만들어서 전달함. 다시 말해 모든 operation을 immutable로 만든다. / 때문에 Wasted Condition이 적다. 기존에는 Mutex걸고 별 난리를 쳤는데 이런걸 고려안해도된다. / 쓰레드가 많아지고, 분산처리가 많아질수록 함수형 프로그램이 각광 받을 수 밖에 없다. / (포프TV, 함수형 프로그래밍, 2017)

  • DRY(Don’t Reat Yourself)와 공유코드 사용(재사용)의 위험성
    • 공유코드: DRY를 의식하고 공유코드를 만들게 됨으로서, 서비스간 결합을 만들 수 있음.
    • 클라이언트 라이브러리: 클라이언트 라이브러리가 서비스의 응집력을 약화시킬 수 있음. / 서버에만 있어야할 로직이 클라이언트 사이드에 존재 하게될 수 도 있음 / 서버를 수정하기 위해 클라이언트를 함께 수정해야하는 불상사도 생길 수 있음
  • Sementic Versioning 유의적 버전관리
    • MAJOR.MINOR.PATCH
    • MAJOR: 하위호환성이 깨진 변경
    • MINOR: 하위 호환성을 유지하면서 새로운 기능들이 추가
    • PATCH: 기존 기능의 버그를 수정
  • 관대한 독자 (Tolerant Reader) 패턴
  • 포스텔의 법칙 혹은 견고성의 법칙
  • 확장-수축패턴

  • 사용자 인터페이스 (User Interface)

     고객이 우리 회사와 어떻게 상호작용할지 정확히 예측할 수 없다는 것을 이해한 후 마이크로서비스가 제공하는 것과 같은 더 세분화된 API를 채택하게되었다. 서비스들이 다양한 방식으로 노출하는 기능들을 서로 결합시킴으로써 데스크톱 애플리케이션, 모바일 기기, 웨어러블 기기의 사용 고객뿐만 아니라 오프라인 상점을 방문하는 등의 물리적 방식을 이용하는 고객에게도 다양한 경험을 심어 줄 수 있게 되었다.
     사용자 인터페이스를 우리가 제공하는 다양한 기능 요소를 한데 엮을 수 있는 구성 가능한 계층으로 생각하라.

    • API 게이트웨이 / 프론트엔드를 위한 백엔드 BFF (Backend For Frontend)
       API 게이트웨이 패턴, BFF라고도 부른다 (MSDN). 백엔드를 특정 사용자 UI 또는 앱으로 제한하여, 클라이언트 앱의 요구사항을 반영한 API게이트웨이를 말한다.
      MSDN에서 얘기하는 BFF의 단점: 내부 MSA 서비스와 결합됨 / 가능한 추가 단일 실패 지점이 만들어짐 / 응답시간증가 / 스케일아웃 제대로 안되면 병목 상태 / 추가 개발 비용 및 유지 관리가 필요 / 개발 병목 상태가 있을 수 있음. (BFF의 단점)
  • 통합 마무리
    • 데이터베이스 통합은 최대한 피하라.
    • REST와 RPC의 장단점을 이해하고, 용청/응답을 통합하는 좋은 출발점으로 REST를 고려하라
    • 오케스트레이션보다는 코레오그래피를 우선하라
    • 포스텔의 법칙을 이해하고 관대한 독자 패턴을 사용해서 호환성을 깨뜨리는 변경과 불필요한 버전을 피하라
    • 구성 계층으로서의 사용자 인터페이스를 생각하라

테스팅

  • 소비자 주도 계약 (consumer driven contract)
    CDCT: 소비자의 기대사항을 테스트 할 수 있도록 코드로 구현한 것
  • 빠른 피드백을 위해 최적화하고, 테스트를 종류별로 적절히 분리하라.
  • 소비자 주도 계약을 이용하여 가능하면 어디서든지 엔드 투 엔드 테스트의 필요성을 줄여라
  • 팀 간 대화의 초점을 맞추기 위해 소비자 주도 계약을 사용하라
  • 테스팅에 더 많을 들이는 것과 실환경에서 빠른 문제의 발견 사이의 절충점을 이해하도록 노력하라 (MTBF와 MTTR 사이의 최적화와 함께)

모니터링

  • 로그스태쉬 (logstash)
  • 키바나 (Kibana)
  • 그래파이트 (Graphite)

후기

 근 3년간 업무와 관련하여 그래픽스 위주로 공부해왔었다. 업무가 서비스기업들에서 채택하고있는 트랜디한 기술스텍과는 멀었기에, 급변하는 기술트랜드에 관심을 기울이지 않았었다. 최근 돼서야 메타버스란 키워드로 드문드문 기회가 생기는 모양이긴하지만 이런 사업이 궤도에 오르려면 아직 멀었다고 생각한다. 아무튼간 주류로부터 어디서 놓힌건지 감도 안왔을 때 이 책을 읽은 것은 제법 흐름정리가 됐다. 앞서 말했듯이, 2015년의 책이었지만 이제 막 MSA가 각광받기 시작할 때 쓰여졌던 책이라 변곡점에서의 관점으로 서술되었기에 오히려 좋았던 것 같다.

 물론 최근 나오는 MSA 서적보다 구체적인 사례나 설계예시가 부족하다. 때문에 책이 비교적 추상적으로 느껴지는 감도 없잖아 있다. 참고로 비교적 최근에 동일저자 샘 뉴먼의 ‘마이크로서비스 도입 이렇게 한다’(샘 뉴먼 저/박재호 역, 2021.01.20)가 출간됐다. 원서는 2019년도 서적이다. 서점에서 얼핏 봤을때는 기본적인 구성과 논조는 유지하면서 앞서 얘기한 부족한 내용들이 추가로 서술됐던 듯 하다.

 이제 어떤 것이 부족하고 뭐를 공부해봐야 하는지 감이왔다. 문제는 공부해야할게 너무 많다는거다🤣…. 부지런히 하나하나 차근차근 공부해나가야겠다.

후속포스트

라고 쓰고 공부해야할 것이라 읽는다.

  • MSA와 gRPC
  • Event Driven Microservice
  • 반응형 프로그래밍 (Rx)
  • 블로킹과 논블로킹

https://www.ibm.com/kr-ko/cloud/learn/soa#toc-soa—pTXVnVY0



2022 ⓒ ChillyMind