22.02.2017 Views

마이크로서비스 아키텍처 구축 : 대용량 시스템의 효율적인 분산 설계 기법_맛보기

샘 뉴먼 저/정성권 역 | 한빛미디어 | 2017년 03월 26,000원

샘 뉴먼 저/정성권 역 | 한빛미디어 | 2017년 03월
26,000원

SHOW MORE
SHOW LESS
  • No tags were found...

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>대용량</strong> <strong>시스템의</strong> <strong>효율적인</strong> <strong>분산</strong> <strong>설계</strong> <strong>기법</strong><br />

Building<br />

Microservices<br />

<strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong><br />

샘 뉴먼 지음<br />

정성권 옮김


| 표지 설명 |<br />

표지 동물은 꿀벌(학명: Apis )로, 우리나라에서는 축산법상 ‘가축’으로 분류되어 있다.<br />

2만여 종의 벌 중 7종만 꿀벌로 간주한다. 꿀벌은 벌꿀을 생산하고 저장할 뿐만 아니<br />

라 밀랍으로 벌집을 만드는 점에서 다른 종과 구분된다. 벌꿀을 수집하는 양봉은 수천<br />

년 동안 인류가 생업으로 종사해왔다.<br />

꿀벌은 수천의 개체가 벌집에서 함께 생활하며 매우 조직적인 사회 구조를 유지하고<br />

있다. 여왕벌, 수벌, 일벌의 세 계급이 존재하며 각 벌집에 여왕벌은 한 마리뿐이<br />

다. 여왕벌은 짝짓기 비행 후 3~5년 동안 생식 능력이 있으며 하루에 2천 개까<br />

지 알을 낳는다. 수벌은 여왕벌과 짝짓기를 하는 수컷 벌로서 가시가 돋친 생식<br />

기 때문에 짝짓기 후 죽는다. 일벌은 생식 능력이 없는 암컷 벌로서 평생 보모, 집<br />

짓기, 먹이 관리, 경비, 장의, 채집 등의 일을 한다. 채집 일을 하는 일벌들은 가까이<br />

있는 자원의 정보를 공유하기 위해 특별한 패턴의 춤을 통해 서로 의사소통한다.<br />

최근 몇 년 동안 ‘군집붕괴현상’으로 알려진 많은 벌종의 감소가 우려할 수준이 되었지만 이 종의 급격한 자연 소멸의 원인<br />

이 아직 밝혀지지 않았다. 기생충, 살충제, 질병 등이 원인이라는 여러 가설이 있지만, 현재까지는 효과적인 예방 조치가 발<br />

견되지 않았다.<br />

<strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong><br />

<strong>대용량</strong> <strong>시스템의</strong> <strong>효율적인</strong> <strong>분산</strong> <strong>설계</strong> <strong>기법</strong><br />

초판 1쇄 발행 2017년 3월 1일<br />

지은이 샘 뉴먼 / 옮긴이 정성권 / 펴낸이 김태헌<br />

감수 박재호 / 베타리더 윤석찬, 신능선<br />

펴낸곳 한빛미디어 (주) / 주소 서울시 마포구 양화로7길 83 한빛미디어(주) IT출판부<br />

전화 02 – 325 – 5544 / 팩스 02 – 336 – 7124<br />

등록 1999년 6월 24일 제10 – 1779호 / ISBN 978 – 89 – 6848 – 341 – 7 93000<br />

총괄 전태호 / 책임편집 김창수 / 기획·편집 박지영 / 교정·조판 김철수<br />

디자인 표지 김연정, 내지 여동일<br />

영업 김형진, 김진불, 조유미 / 마케팅 박상용, 송경석, 변지영 / 제작 박성우, 김정우<br />

이 책에 대한 의견이나 오탈자 및 잘못된 내용에 대한 수정 정보는 한빛미디어(주)의 홈페이지나 아래 이메일로<br />

알려주십시오. 잘못된 책은 구입하신 서점에서 교환해드립니다. 책값은 뒤표지에 표시되어 있습니다.<br />

한빛미디어 홈페이지 www.hanbit.co.kr / 이메일 ask@hanbit.co.kr<br />

© 2017 Hanbit Media Inc.<br />

Authorized Korean translation of the English edition of Building Microservices<br />

ISBN 9781491950357 © 2015 Sam Newman<br />

This translation is published and sold by permission of O’Reilly Media, Inc., which owns or controls<br />

all rights to publish and sell the same.<br />

이 책의 저작권은 오라일리와 한빛미디어(주)에 있습니다.<br />

저작권법에 의해 한국내에서 보호를 받는 저작물이므로 무단전재와 복제를 금합니다.<br />

지금 하지 않으면 할 수 없는 일이 있습니다.<br />

책으로 펴내고 싶은 아이디어나 원고를 메일 ( writer@hanbit.co.kr ) 로 보내주세요.<br />

한빛미디어(주)는 여러분의 소중한 경험과 지식을 기다리고 있습니다.


Building<br />

Microservices<br />

<strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


지은이·옮긴이 소개<br />

지은이 샘 뉴먼<br />

Sam Newman<br />

소트워크스 사에서 고객들의 사내 시스템을 <strong>설계</strong>하는 아키텍트로 일하고 있다. 여러 나라 여러<br />

분야의 회사들과 협업하며 개발과 IT 운영 영역을 넘나들어 왔다. 그에게 어떤 일을 하는지 묻는<br />

다면 “사람들과 함께 더 나은 소프트웨어 시스템을 만드는 일을 합니다”라고 답할 것이다. 샘은<br />

기사를 쓰고, 컨퍼런스에서 발표하며, 가끔 오픈 소스 프로젝트에 커밋하고 있다.<br />

옮긴이 정성권 klimtever@gmail.com<br />

팜 Palm , 심비안 Symbian , 바다 Bada 스마트폰 소프트웨어와 모바일 보안 플랫폼인 KNOX 기업용<br />

서비스의 개발을 담당했으며 현재 <strong>마이크로서비스</strong> 기반의 IoT 서비스를 개발 중이다. 대규모<br />

<strong>분산</strong> 시스템 <strong>설계</strong>와 운영 방법론에 주목해 왔으며 최근에는 Rx, Dropwizard와 Ratpack을<br />

통한 반응형/비동기 프로그래밍에 관심이 많다. 공저로는 『ABOUT.NET XML 웹 서비스』(영<br />

진닷컴, 2002 )와 『PHP 웹 서버 <strong>구축</strong>하기』(사이버출판사, 2000 )가 있다.<br />

4


추천의 글<br />

최근 클라우드 환경이 일반화되면서 많은 서비스가 클라우드로 이전하거나 클라우드에서 시작<br />

되고 있다. 하지만 클라우드의 확장성과 안정성은 공짜로 얻어지는 산물이 아니다. 기존의 일반<br />

적인 애플리케이션 개발 방법을 그대로 적용하면 비용절감, 탄력성, 회복성, 배포 편의성과 같<br />

은 좋은 특성을 누리기 어려우며 오히려 서비스의 품질이 떨어지는 경우도 있다. 빠르게 변하는<br />

클라우드 시대에 걸맞게 <strong>아키텍처</strong> <strong>설계</strong>, 서비스 모델링, 실제 구현, 통합, 배포, 테스트, 모니터<br />

링, 확장에 전력을 다해야 비로소 고객 만족을 극대화하는 서비스를 제공할 수 있다.<br />

이 책은 거대한 모놀리식 시스템과 반대되는 <strong>마이크로서비스</strong>를 중심으로 클라우드 시대의 생존<br />

방법을 제시하며 실제 사례를 중심으로 실무에 바로 도움이 되는 내용을 담았다. 따라서 아키텍<br />

처 <strong>설계</strong>, 실제 구현, 운영 업무를 진행하는 과정에서 많은 도움을 줄 것이다. 미시적인 컴퓨터 프<br />

로그래밍 부문에서 리팩토링이 기술 부채를 줄이는 수단이라면, 거시적인 서비스 개발과 운영<br />

부문에서는 <strong>마이크로서비스</strong>가 기술 부채를 줄이는 강력한 수단이다. 이 책은 현대적인 컴퓨팅<br />

환경에 적응하기 위한 좋은 길라잡이가 될 것이다.<br />

박재호<br />

「컴퓨터 vs 책」 블로그(https://jhrogue.blogspot.kr) 운영자<br />

한국 개발자들은 실제 사례나 샘플 코드를 실전에 바로 활용할 수 있는 책을 좋아한다. 이 책에<br />

는 <strong>마이크로서비스</strong> 개발에 대한 샘플 코드는 전혀 없지만, 대신 <strong>마이크로서비스</strong> <strong>아키텍처</strong>를 구<br />

축하려는 이들이 직면할 많은 <strong>설계</strong>적 고충과 문제점, 고려사항에 대한 실질적 충고와 해설을<br />

담았다. <strong>아키텍처</strong>는 한번 잘못 <strong>설계</strong>하면 되돌리기 매우 어려운 만큼 처음부터 충분한 고민이 필<br />

요하다. <strong>마이크로서비스</strong> <strong>아키텍처</strong>는 <strong>분산</strong> 컴퓨팅과 클라우드 기반 서비스가 발전하면서 데브옵<br />

스 기반 개발 문화의 변화와 필연적으로 조우한다. 코드 그 이상의 주제를 놓고 고민한다면 꼭<br />

읽어봐야 할 필독서다.<br />

윤석찬<br />

아마존 웹 서비스(AWS) 테크에반젤리스트<br />

5


이제 모바일과 클라우드가 대중화되어 소비자의 다양한 니즈에 빠르게 대응할 수 있는 애플리케<br />

이션 개발환경이 요구됩니다. 업계의 최근 화두인 <strong>마이크로서비스</strong> <strong>아키텍처</strong>는, 커다란 모듈로<br />

이뤄진 전통적인 모놀리식 방식이 아닌, 애플리케이션을 작은 서비스 단위로 <strong>설계</strong>하고 지속적<br />

관리와 배포를 지향하여 이러한 요구사항에 부합합니다.<br />

이 책은 <strong>마이크로서비스</strong>를 처음 접하는 이들의 이해를 돕고, 애플리케이션과 서비스 개발을 검<br />

토하는 분들에게 <strong>아키텍처</strong>적 접근 방법을 제시합니다. 또한 애플리케이션 수명주기 전반에 걸쳐<br />

<strong>마이크로서비스</strong>를 실제로 적용할 때 고려할 사항을 본질적 관점에서 서술합니다. 마이크로서비<br />

스가 무엇인지 궁금하고 당장 실무에 적용하고자 하는 모든 분에게 이 책을 추천합니다.<br />

신능선<br />

Microsoft Korea Technologist<br />

6


옮긴이의 말<br />

한때 소프트웨어 <strong>아키텍처</strong> 분야에서 웹 서비스나 SOA 같은 용어가 유행이었다면 최근의 화두<br />

는 단연 <strong>마이크로서비스</strong>다. 서비스를 출시하는 최근 업체들은 그들의 개발 스토리에 마이크로서<br />

비스로의 성공적 전환과 운영이 빠지지 않으며 각종 서버 기술 컨퍼런스에서도 단골 주제가 되<br />

었다. 여러분이 잘 알고 있는 넷플릭스와 AWS 외에도 이 책에서 소개한 길트 쇼핑몰과 REA<br />

같은 부동산 회사의 사례에서 볼 수 있듯이 성공적인 <strong>마이크로서비스</strong> 도입이 기술 및 운영적인<br />

면을 넘어 비즈니스 확장에도 중요한 역할을 하고 있다. 여러분이 남들도 잘하는 마이크로서비<br />

스를 나도 한번 시작해보거나 더 잘 해보고 싶은 생각으로 방법론과 조언을 구하며 이 책을 집어<br />

들었다면 아주 적합한 선택을 했다고 말하고 싶다.<br />

이 책의 저자 샘 뉴먼은 소트워크스의 기술 전문가이자 아키텍트로, 자신의 풍부한 실전 경험을<br />

바탕으로 <strong>마이크로서비스</strong>의 개념을 총체적으로 다루면서도 시중의 개념서에서 부족했던 실질<br />

적인 접근 방법을 소개했다. <strong>마이크로서비스</strong>를 도입하는 데 있어 프로그래밍 언어, 프레임워크,<br />

도구와 같은 특정 기술의 종속을 경계하므로 기술 자체를 깊이 다루지는 않았지만 필자가 경험<br />

했거나 미래가 밝은 유용한 기술과 도구를 소개하는 데는 인색하지 않았다. 번역 과정에서 역자<br />

가 이미 도입한 기술과 방법을 책에서 발견했을 때는 올바른 방향으로 가고 있다는 확신이 들어<br />

서 좋았고 경험하지 않은 새로운 도구와 아이디어를 만나면 역자의 시스템을 개선할 수 있다는<br />

기대를 가지게 되어 좋았다. 이 책의 독자들도 유사한 경험을 하지 않을까 기대한다.<br />

역자 주변의 개발자들이 마틴 파울러가 블로그에서 소개한 <strong>마이크로서비스</strong>를 접하면서 관심을<br />

가지기 시작한 게 겨우 몇 해 전으로 기억하지만, 현재는 역자가 개발 중인 서비스뿐 아니라 관<br />

련 업체들도 <strong>마이크로서비스</strong> 개발 방식으로 개발하고 있다. 그러나 책에서 언급한 것처럼 은총<br />

알은 없으니 경험이 많지 않거나 비즈니스 도메인에 대한 이해가 낮다면 무리한 <strong>마이크로서비스</strong><br />

의 도입보다는 모놀리스에서 시작해서 점진적으로 분해하는 것이 좋다. 이처럼 <strong>마이크로서비스</strong><br />

에 대한 균형적인 시각을 제공하는 것은 이 책의 장점 중 하나다.<br />

이 책은 정말로 <strong>마이크로서비스</strong>에 대한 거의 모든 것, 즉 <strong>설계</strong>, 개발, 통합, 배포, 테스팅, 모니<br />

터링, 보안, 운영, 조직까지 총망라한다. <strong>마이크로서비스</strong>에 대한 이론 체계를 정립해줄 뿐 아니<br />

라 사람과 조직 간에 발생하는 인간적인 요소도 간과하기 쉽지만 중요한 부분임을 일깨워준다.<br />

7


technical program<br />

따라서 이 책은 아키텍트가 되려는 개발자, 중견 개발자, 기술 리더, 서비스 TPM<br />

manager 이 되려는 독자에게 좋은 지침서다. 특히 아키텍트에게 요구되는 현대적인 자질이 2장에<br />

잘 설명되어 있으므로 아키텍트가 되려는 분은 2장을 일독하길 권하고 싶다. 이 책에서는 마이<br />

크로서비스로의 전환을 통해 성장한 업체의 성공 사례는 물론 우리도 겪을 수 있고 교훈이 될<br />

실패 사례와 부끄럽지만 흥미로운 필자의 실수담도 소개된다. 혹자는 <strong>마이크로서비스</strong>가 단순<br />

히 모놀리식 애플리케이션을 잘 분리하면 되는 것 아니냐고 반문할 수 있겠지만 그 이상의 것<br />

을 이 책을 통해 발견하기 바란다.<br />

이상하게 들릴지 모르지만, <strong>마이크로서비스</strong> <strong>아키텍처</strong>를 도입하고자 이 책을 참고한다면 여러분<br />

팀은 경험 많고 유능한 아키텍트를 고용한 효과를 볼 수 있다. 필자와 협업하는 해외 업체 한 곳<br />

은 이 책을 개발 및 데브옵스 devops 의 지침서로 활용하여 그들의 모놀리식 애플리케이션을 마이<br />

크로서비스화했다. 이 책에 소개된 효과적인 도구, 즉 테라폼, 앤서블, 드롭위자드, 집킨, 칸슬<br />

등을 개발 및 배포 파이프라인에 적극적으로 수용했고 원칙과 실천 사항을 정의해 마이크로서비<br />

스에 필요한 거버넌스를 지켜나갔다. 소프트웨어의 개발과 시스템 <strong>구축</strong>에는 정말로 많은 의사<br />

결정과 절충안이 필요하지만 필자가 이미 경험한 고민과 해결 방안은 우리를 <strong>마이크로서비스</strong>의<br />

함정에 빠지지 않고 안전한 곳으로 인도해준다.<br />

번역하면서 개발자가 이해할 수 있는 우리말을 선택하고 의미 손실 없이 옮기고자 수없이 고민<br />

했다. 번역된 용어가 낯설 것으로 예상되는 곳에는 적극적으로 첨자를 추가했고, 새로운 도구와<br />

용어, 인물에 관한 주석도 열심히 달아 독자의 이해를 돕고자 노력했다. 여전히 부족한 점이 많<br />

겠지만 독자 여러분의 관대함을 간절히 기대한다.<br />

끝으로 오랜 기간 기다려주신 한빛미디어의 박지영님과 관련자 여러분께 감사의 마음을 전하며,<br />

첨삭 지도에 가까운 감수를 해주신 전문 번역가이자 파워 블로거이신 박재호님, 독자의 입장에<br />

서 좋은 피드백을 주신 윤석찬님께도 깊은 감사를 드린다.<br />

정성권<br />

8


이 책에 대하여<br />

<strong>마이크로서비스</strong>는 <strong>분산</strong> 시스템에 대한 접근 방식으로, 각자의 생명주기를 가지고 협력하는 세분<br />

화한 서비스 사용을 장려한다. <strong>마이크로서비스</strong>는 주로 비즈니스 도메인을 기반으로 모델링하므<br />

로 기존의 계층형 <strong>아키텍처</strong>에서 발생하는 문제를 회피한다. 또한 <strong>마이크로서비스</strong>는 지난 10년<br />

간 출현한 새로운 기술과 <strong>기법</strong>을 통합함으로써 서비스 지향 <strong>아키텍처</strong>를 구현할 때 겪는 많은 함<br />

정을 피할 수 있게 해준다.<br />

이 책은 넷플릭스, 아마존, 길트 및 REA 그룹을 포함해 전 세계에서 <strong>마이크로서비스</strong>를 사용하<br />

는 구체적인 예로 가득 차 있다. 그들 모두 이 <strong>아키텍처</strong>가 제공하는 향상된 자율성이 커다란 혜<br />

택임을 발견했다.<br />

대상 독자<br />

세분화된 <strong>마이크로서비스</strong> <strong>아키텍처</strong>의 의미가 매우 광범위하듯 이 책 또한 광범위한 내용을 다<br />

룬다. 따라서 <strong>설계</strong>, 개발, 배포, 테스팅, 유지보수 측면에 관심이 있는 사람들이 좋아할 것이다.<br />

신규 애플리케이션이나 기존 모놀리식 시스템을 분해하는 분야에 관계없이 세분화된 <strong>아키텍처</strong><br />

를 향한 여정을 시작한 사람들에게 도움이 될 실질적이고 풍부한 조언을 제공한다. 또한 모든<br />

논란의 실체를 이해하고 싶은 사람들에게 도움이 될 것이므로 <strong>마이크로서비스</strong>가 여러분에게 적<br />

합한지 판단할 수 있게 될 것이다.<br />

집필 배경<br />

필자는 수년 전부터 소프트웨어를 빠르게 제공하도록 돕는 애플리케이션 <strong>아키텍처</strong>를 생각하기<br />

시작했다. 인프라스트럭처 자동화, 테스팅, 지속적 배포 기술이 도움이 될 수 있지만 <strong>시스템의</strong><br />

기본 <strong>설계</strong>가 변경을 쉽게 허용하지 않는다면 원하는 것을 이루는 데 한계가 있다는 것을 깨달<br />

았다.<br />

9


같은 시기에 많은 조직이 확장성 향상, 팀 자율성 증가, 신기술 도입 용이성 개선 등의 목표 아<br />

래 세분화된 <strong>아키텍처</strong>를 실험하고 있었다. 소트워크스 및 다른 곳의 동료들과 필자는 그간의 경<br />

험을 통해 독립된 수명주기의 서비스를 많이 사용할수록 이들을 처리하기가 더 어렵다는 사실을<br />

확인했다. 여러 면에서 이 책은 그 당시 필자에게 엄청난 도움이 되었을 그 무엇, 즉 마이크로서<br />

비스를 이해하는 데 필요한 다양한 주제를 한꺼번에 확인할 수 있는 곳이다!<br />

오늘날의 <strong>마이크로서비스</strong><br />

<strong>마이크로서비스</strong>는 급변하는 주제다. 비록 그 개념은 새로운 것이 아니더라도(그 용어는 새로울<br />

지라도) 전 세계 사람들의 경험은 새로운 기술이 출현할 때마다 <strong>마이크로서비스</strong>를 사용하는 방<br />

법에 상당한 영향을 끼치고 있다. 필자는 세부 구현이 생각보다 빨리 변한다는 것을 잘 알고 있<br />

으므로 이 책에서는 특정 기술보다 <strong>마이크로서비스</strong>의 개념과 사상에 집중하려 노력했다. 그럼<br />

에도 불구하고 필자는 여러분이 향후 몇 년 안에 <strong>마이크로서비스</strong>가 어디에 적합하고 어떻게 잘<br />

사용할 수 있는지에 대해 더 많이 배울 것으로 기대한다.<br />

이 책에서는 <strong>마이크로서비스</strong>의 본질을 밝히기 위해 최선을 다했지만 만약 이 주제에 더 많은 관<br />

심이 있다면 최고의 기술 수준을 유지하도록 수년간 지속적인 학습을 하라!<br />

이 책의 구성<br />

이 책은 주제별로 구성되어 있다. 따라서 여러분이 가장 관심 있는 특정 주제로 바로 이동할 수<br />

있다. 각 장은 이전 장에서 언급한 용어와 개념을 참조하는 데 최선을 다했으며, 경험이 풍부하<br />

다고 생각하는 분들도 이 책의 모든 장에서 흥미로운 주제를 발견하기 기대한다. 특히 2장은 폭<br />

넓은 주제를 다루며 이 책의 전개에 대해 이야기하니, 다른 주제를 더 깊이 연구하고자 한다면 2<br />

장을 먼저 읽어보기를 권한다.<br />

10


<strong>마이크로서비스</strong> 관련 경험이 전혀 없는 분들은 처음부터 순서대로 읽어가는 것이 좋다.<br />

각 장의 주제는 다음과 같다.<br />

1장 <strong>마이크로서비스</strong><br />

<strong>마이크로서비스</strong>가 가져다주는 주요 혜택을 몇몇 단점과 함께 소개한다.<br />

2장 진화적 아키텍트<br />

아키텍트로서 상충관계의 타협점을 찾는 과정에서 직면하는 어려움을 논의하고 마이크로서<br />

비스에 대해 생각해야 하는 많은 사항을 구체적으로 다룬다.<br />

3장 서비스 모델링하기<br />

우리 생각을 집중하는 데 도움이 될 도메인 주도 <strong>설계</strong> 기술을 사용해서 <strong>마이크로서비스</strong>의 경<br />

계를 정의하기 시작한다.<br />

4장 통합<br />

어떤 서비스 협업 기술이 가장 도움이 될지 논의하며 특정 기술의 구현체를 보다 깊이 살펴보<br />

기 시작한다. 사용자 인터페이스에 대한 주제를 탐구하며 레거시 제품과 상용 제품을 통합하<br />

는 주제도 살펴본다.<br />

5장 모놀리스 분해하기<br />

많은 사람이 대규모이며 변경이 어려운 모놀리식 <strong>시스템의</strong> 해독제로서 <strong>마이크로서비스</strong>에 주<br />

목한다. 이것이 이 장에서 다루는 주제다.<br />

6장 배포<br />

배포를 포함하여 이 책의 몇몇 주제는 최근의 기술 변화에 영향을 받았고, 이 장에서는 그중<br />

배포에 대해 탐구할 것이다.<br />

11


7장 테스팅<br />

별개의 여러 서비스를 배포할 때 특히 우려가 되는 테스팅의 주제에 대해 깊이 살펴본다. 특<br />

히 주목할 점은 소프트웨어 품질 보장에 도움을 주는 소비자 주도 계약의 역할이다.<br />

8장 모니터링<br />

출시 후에 문제가 발생한다면 운영 전에 수행한 테스트가 도움이 되지 않았다는 의미다. 세분<br />

화된 시스템을 모니터링하고 <strong>분산</strong> 시스템에서 출현하는 복잡성을 다루는 방법을 살펴본다.<br />

9장 보안<br />

<strong>마이크로서비스</strong>의 보안 측면을 검토하고 사용자 대 서비스와 서비스 대 서비스 인증 및 권한<br />

처리 방법을 고민한다. 보안은 컴퓨팅에서 매우 중요한 주제지만 너무 쉽게 간과된다. 필자는<br />

보안 전문가는 아니지만 최소한 이 장의 내용이 시스템, 특히 <strong>마이크로서비스</strong> 시스템을 <strong>구축</strong><br />

할 때 인지해야 할 보안 측면을 고려하는 데 도움이 되기를 바란다.<br />

10장 콘웨이의 법칙과 시스템 <strong>설계</strong><br />

조직 구조와 <strong>아키텍처</strong>의 상호 작용에 중점을 둔다. 필자는 이 두 가지가 서로 조화를 유지하<br />

지 못한다면 문제가 발생한다는 것을 깨달았다. 그 원인을 밝혀내고 팀의 구조와 시스템 설<br />

계를 맞추는 여러 방법을 고려한다.<br />

11장 대규모 <strong>마이크로서비스</strong><br />

앞에서 다룬 모든 것을 대규모로 운영하기 위한 검토를 시작한다. 수많은 서비스와 늘어난<br />

트래픽으로 인해 높아진 실패 가능성을 처리하는 방법을 알아본다.<br />

12장 종합 정리<br />

<strong>마이크로서비스</strong>를 다른 것과 차별화하는 핵심 요소를 알아본다. 그 요소란 <strong>마이크로서비스</strong><br />

7원칙과 이 책에서 설명한 핵심 내용들이다.<br />

12


감사의 글<br />

린디 스테판 Lindy Stephens 이 없었다면 이 책은 세상의 빛을 보지 못했을 것이다. 그녀는 내가 이<br />

여정을 시작하도록 격려했고 스트레스가 많은 집필 과정 내내 응원해주고 도와준 최고의 파트<br />

너였다. 그녀에게 이 책을 바친다. 그리고 항상 나의 곁을 지켜주신 아버지 호와드 뉴먼 Howard<br />

Newman 께도 이 책을 바친다. 이 책은 두 분을 위한 것이다.<br />

집필 기간 내내 상세하게 피드백을 해주며 이 책의 틀을 잡아준 벤 크리스텐센 Ben Christensen , 비<br />

벡 수브라매니암 Vivek Subramaniam , 마틴 파울러 Martin Fowler 에게 특히 감사하고 싶다. 또한 이 책에<br />

서 제시한 아이디어를 토론하느라 엄청난 맥주를 함께 마신 제임스 루이스 James Lewis 에게도 감<br />

사하다는 말을 전한다. 이 책은 그들의 도움과 조언이 없었다면 빛을 보지 못했을 것이다.<br />

그 외 많은 분이 이 책의 초기 버전에 도움과 피드백을 주었다. 특히 필자가 여기까지 오는 데<br />

도움을 준 케인 베너블즈 Kane Venables , 아난드 크리시나스와미 Anand Krishnaswamy , 켄트 맥닐 Kent<br />

McNeil , 찰스 헤인스 Charles Haynes , 크리스 포드 Chris Ford , 아이디 루이스 Aidy Lewis , 윌 템즈 Will Thames ,<br />

존 입스 Jon Eaves , 롤프 러셀 Rolf Russell , 바드리나쓰 자나키라만 Badrinath Janakiraman , 대니얼 브라이언<br />

트 Daniel Bryant , 이안 로빈슨 Ian Robinson , 짐 웨버 Jim Webber , 스튜어트 글리도 Stewart Gleadow , 이반 보<br />

처 Evan Bottcher , 에릭 소드 Eric Sword , 올리비아 레오나드 Olivia Leonard (특별한 순서가 있는 것은 아<br />

니다)와 소트워크스 및 업계 전반의 모든 동료에게 감사하고 싶다.<br />

끝으로 이 책을 저술하도록 독려해준 마이크 루키드 Mike Loukides , 편집자인 브라이언 맥도날드<br />

Brian MacDonald , 레이첼 모나간 Rachel Monaghan , 크리스틴 브라운 Kristen Brown , 배치 왈리츠스키 Betsy<br />

Waliszewski 를 포함해서 오라일리의 모든 분과 보이지 않는 곳에서 도움을 준 모든 분에게 감사를<br />

드린다.<br />

13


CONTENTS<br />

지은이·옮긴이 소개 ......................................................................................................... 4<br />

추천의 글 ....................................................................................................................... 5<br />

옮긴이의 말 .................................................................................................................... 7<br />

이 책에 대하여 ................................................................................................................ 9<br />

감사의 글 ..................................................................................................................... 13<br />

CHAPTER 1 <strong>마이크로서비스</strong><br />

1.1 <strong>마이크로서비스</strong>란 ........................................................................................................ 28<br />

1.1.1 작고, 한 가지 일을 잘하는 데 주력 ....................................................................... 28<br />

1.1.2 자율성 ........................................................................................................... 30<br />

1.2 주요 혜택 .................................................................................................................. 31<br />

1.2.1 기술 이기종성 ................................................................................................. 31<br />

1.2.2 회복성 ........................................................................................................... 33<br />

1.2.3 확장성 ........................................................................................................... 33<br />

1.2.4 배포 용이성 .................................................................................................... 34<br />

1.2.5 조직 부합성 .................................................................................................... 35<br />

1.2.6 조합성 ........................................................................................................... 35<br />

1.2.7 대체 가능성을 위한 최적화 ................................................................................ 36<br />

1.3 서비스 지향 <strong>아키텍처</strong>란 ................................................................................................ 37<br />

1.4 기타 분해 기술 ............................................................................................................ 38<br />

1.4.1 공유 라이브러리 .............................................................................................. 38<br />

1.4.2 모듈 .............................................................................................................. 39<br />

1.5 은총알은 없다 ............................................................................................................. 40<br />

1.6 마치며 ...................................................................................................................... 41<br />

14


CHAPTER 2 진화적 아키텍트<br />

2.1 부정확한 비교 ............................................................................................................. 43<br />

2.2 아키텍트에 대한 진화적 관점 ......................................................................................... 45<br />

2.3 구역화 ...................................................................................................................... 47<br />

2.4 원칙적인 접근법 .......................................................................................................... 49<br />

2.4.1 전략적 목표 .................................................................................................... 49<br />

2.4.2 원칙 .............................................................................................................. 50<br />

2.4.3 실천 사항 ....................................................................................................... 50<br />

2.4.4 원칙과 실천 사항의 결합 ................................................................................... 51<br />

2.4.5 실제 사례 ....................................................................................................... 51<br />

2.5 필수 기준 .................................................................................................................. 52<br />

2.5.1 모니터링 ........................................................................................................ 53<br />

2.5.2 인터페이스 ..................................................................................................... 53<br />

2.5.3 <strong>아키텍처</strong> 안정성 .............................................................................................. 54<br />

2.6 코드를 통한 통제 ......................................................................................................... 54<br />

2.6.1 본보기 ........................................................................................................... 55<br />

2.6.2 맞춤형 서비스 템플릿 ....................................................................................... 55<br />

2.7 기술 부채 .................................................................................................................. 57<br />

2.8 예외 처리 .................................................................................................................. 58<br />

2.9 중앙에서의 거버넌스와 지휘 .......................................................................................... 58<br />

2.10 팀 만들기 .................................................................................................................. 60<br />

2.11 마치며 ...................................................................................................................... 61<br />

CHAPTER 3 서비스 모델링하기<br />

3.1 뮤직코퍼레이션 소개 .................................................................................................... 63<br />

15


CONTENTS<br />

3.2 무엇이 좋은 서비스를 만드는가? .................................................................................... 64<br />

3.2.1 느슨한 결합 .................................................................................................... 65<br />

3.2.2 강한 응집력 .................................................................................................... 65<br />

3.3 경계가 있는 콘텍스트 ................................................................................................... 65<br />

3.3.1 감춰진 공유 모델 ............................................................................................. 66<br />

3.3.2 모듈과 서비스 ................................................................................................. 68<br />

3.3.3 성급한 분해 .................................................................................................... 69<br />

3.4 비즈니스 능력 ............................................................................................................. 70<br />

3.5 거북이 밑에 거북이 ...................................................................................................... 70<br />

3.6 비즈니스 콘셉트 관점에서의 커뮤니케이션 ....................................................................... 72<br />

3.7 기술적 경계 ................................................................................................................ 72<br />

3.8 마치며 ...................................................................................................................... 74<br />

CHAPTER 4 통합<br />

4.1 이상적인 통합 기술 모색 ............................................................................................... 75<br />

4.1.1 호환성을 깨뜨리는 변경 피하기 .......................................................................... 76<br />

4.1.2 기술 중립적인 API 생성 .................................................................................... 76<br />

4.1.3 소비자를 위한 서비스 단순화 ............................................................................. 76<br />

4.1.4 내부 구현 상세 감추기 ...................................................................................... 77<br />

4.2 고객과의 인터페이싱 .................................................................................................... 77<br />

4.3 공유 데이터베이스 ....................................................................................................... 77<br />

4.4 동기와 비동기 ............................................................................................................. 79<br />

4.5 오케스트레이션과 코레오그래피 ..................................................................................... 80<br />

4.6 원격 프로시저 호출 ...................................................................................................... 83<br />

4.6.1 기술 결합 ....................................................................................................... 84<br />

4.6.2 지역 호출은 원격 호출과 다르다 ......................................................................... 85<br />

4.6.3 취성 .............................................................................................................. 85<br />

16


4.6.4 RPC는 형편없는가? ........................................................................................ 87<br />

4.7 REST ....................................................................................................................... 88<br />

4.7.1 REST와 HTTP ............................................................................................... 88<br />

4.7.2 애플리케이션 상태 엔진으로서의 하이퍼미디어 ...................................................... 89<br />

4.7.3 JSON, XML 또는 다른 것? ............................................................................... 92<br />

4.7.4 지나친 편의를 주의하라 .................................................................................... 93<br />

4.7.5 HTTP 기반 REST의 단점 ................................................................................. 94<br />

4.8 비동기 이벤트 기반의 협업 구현 ..................................................................................... 95<br />

4.8.1 기술 선택 ....................................................................................................... 96<br />

4.8.2 비동기 <strong>아키텍처</strong>의 복잡성 ................................................................................. 97<br />

4.9 상태 기계로서의 서비스 ................................................................................................ 99<br />

4.10 반응형 확장 .............................................................................................................. 100<br />

4.11 <strong>마이크로서비스</strong> 세계에서 코드 재사용의 위험과 DRY ...................................................... 100<br />

4.11.1 클라이언트 라이브러리 ................................................................................... 101<br />

4.12 참조에 의한 접근 ....................................................................................................... 103<br />

4.13 버전 관리 ................................................................................................................ 104<br />

4.13.1 가능하면 지연하기 ......................................................................................... 104<br />

4.13.2 호환성을 깨뜨리는 변경 일찍 찾아내기 .............................................................. 106<br />

4.13.3 유의적 버전 관리 ........................................................................................... 106<br />

4.13.4 다른 엔드포인트와 공존 .................................................................................. 107<br />

4.13.5 다수의 병행 서비스 버전 사용하기 .................................................................... 109<br />

4.14 사용자 인터페이스 ..................................................................................................... 110<br />

4.14.1 디지털을 향해 ............................................................................................... 111<br />

4.14.2 제약 ............................................................................................................ 111<br />

4.14.3 API 구성 ...................................................................................................... 112<br />

4.14.4 UI 부분 구성 ................................................................................................. 113<br />

4.14.5 프론트엔드를 위한 백엔드 ............................................................................... 115<br />

4.14.6 하이브리드 방식 ............................................................................................ 118<br />

17


CONTENTS<br />

4.15 외부 소프트웨어와 통합 .............................................................................................. 118<br />

4.15.1 통제 부족 ..................................................................................................... 119<br />

4.15.2 맞춤화 ......................................................................................................... 119<br />

4.15.3 스파게티 통합 ............................................................................................... 120<br />

4.15.4 여러분 방식대로 ............................................................................................ 120<br />

4.15.5 교살자 패턴 .................................................................................................. 123<br />

4.16 마치며 .................................................................................................................... 124<br />

CHAPTER 5 모놀리스 분해하기<br />

5.1 접합부가 중요하다 ..................................................................................................... 125<br />

5.2 뮤직코퍼레이션 분해하기 ............................................................................................ 126<br />

5.3 모놀리스를 분리하는 이유 ........................................................................................... 128<br />

5.3.1 변경의 속도 .................................................................................................. 128<br />

5.3.2 팀 구조 ........................................................................................................ 128<br />

5.3.3 보안 ............................................................................................................ 128<br />

5.3.4 기술 ............................................................................................................ 129<br />

5.4 뒤엉킨 의존성 ........................................................................................................... 129<br />

5.5 데이터베이스 ............................................................................................................ 129<br />

5.6 문제에 대처하기 ........................................................................................................ 130<br />

5.7 예: 외부 키 관계 깨뜨리기 ........................................................................................... 131<br />

5.8 예: 공유 정적 데이터 .................................................................................................. 133<br />

5.9 예: 공유 데이터 ........................................................................................................ 134<br />

5.10 예: 공유 테이블 ........................................................................................................ 136<br />

5.11 데이터베이스 리팩토링 ............................................................................................... 137<br />

5.11.1 단계적인 분리 ............................................................................................... 137<br />

5.12 트랜잭션의 경계 ........................................................................................................ 138<br />

5.12.1 나중에 재시도하기 ......................................................................................... 140<br />

18


5.12.2 전체 작업 중지하기 ........................................................................................ 140<br />

5.12.3 <strong>분산</strong> 트랜잭션 ............................................................................................... 141<br />

5.12.4 그렇다면 무엇을 해야 할까? ............................................................................. 142<br />

5.13 리포팅 .................................................................................................................... 142<br />

5.14 리포팅 데이터베이스 .................................................................................................. 143<br />

5.15 서비스 호출을 통한 데이터 추출 ................................................................................... 145<br />

5.16 데이터 펌프 .............................................................................................................. 146<br />

5.16.1 대체 종착지 .................................................................................................. 148<br />

5.17 이벤트 데이터 펌프 .................................................................................................... 148<br />

5.18 백업 데이터 펌프 ....................................................................................................... 150<br />

5.19 실시간을 향해 ........................................................................................................... 150<br />

5.20 변경 비용 ................................................................................................................ 151<br />

5.21 원인 파악 ................................................................................................................ 152<br />

5.22 마치며 .................................................................................................................... 152<br />

CHAPTER 6 배포<br />

6.1 지속적 통합이란 ........................................................................................................ 153<br />

6.1.1 정말로 하고 있는가? ....................................................................................... 154<br />

6.2 지속적 통합을 <strong>마이크로서비스</strong>로 매핑하기 ..................................................................... 155<br />

6.3 빌드 파이프라인과 지속적 배포 .................................................................................... 158<br />

6.3.1 그리고 피할 수 없는 예외 ................................................................................ 159<br />

6.4 플랫폼별 산출물 ........................................................................................................ 160<br />

6.5 운영 체제 산출물 ....................................................................................................... 161<br />

6.6 커스텀 이미지 ........................................................................................................... 162<br />

6.6.1 산출물로서의 이미지 ...................................................................................... 165<br />

6.6.2 불변 서버 ..................................................................................................... 165<br />

6.7 환경 ....................................................................................................................... 166<br />

19


CONTENTS<br />

6.8 서비스 환경 구성 ....................................................................................................... 168<br />

6.9 서비스와 호스트 매핑 ................................................................................................. 169<br />

6.9.1 호스트당 다수의 서비스 .................................................................................. 169<br />

6.9.2 애플리케이션 컨테이너 ................................................................................... 171<br />

6.9.3 호스트당 단일 서비스 ..................................................................................... 173<br />

6.9.4 서비스로서의 플랫폼 ...................................................................................... 174<br />

6.10 자동화 .................................................................................................................... 175<br />

6.10.1 자동화의 위력에 대한 두 가지 사례 연구 ............................................................. 176<br />

6.11 물리 머신에서 가상화로 .............................................................................................. 177<br />

6.11.1 전통적 가상화 ............................................................................................... 177<br />

6.11.2 베이그런트 ................................................................................................... 178<br />

6.11.3 리눅스 컨테이너 ............................................................................................ 179<br />

6.11.4 도커 ............................................................................................................ 181<br />

6.12 배포 인터페이스 ........................................................................................................ 183<br />

6.12.1 환경 정의 ..................................................................................................... 184<br />

6.13 마치며 .................................................................................................................... 186<br />

CHAPTER 7 테스팅<br />

7.1 테스트의 종류 ........................................................................................................... 189<br />

7.2 테스트의 범위 ........................................................................................................... 191<br />

7.2.1 단위 테스트 .................................................................................................. 192<br />

7.2.2 서비스 테스트 ............................................................................................... 193<br />

7.2.3 엔드 투 엔드 테스트 ....................................................................................... 194<br />

7.2.4 절충안 ......................................................................................................... 195<br />

7.2.5 얼마나 많은 테스트가 필요할까? ....................................................................... 195<br />

7.3 서비스 테스트 구현하기 .............................................................................................. 196<br />

7.3.1 목 또는 스텁 사용하기 .................................................................................... 196<br />

20


7.3.2 더 영리한 스텁 서비스 .................................................................................... 197<br />

7.4 까다로운 엔드 투 엔드 테스트 ...................................................................................... 198<br />

7.5 엔드 투 엔드 테스팅의 단점 ......................................................................................... 200<br />

7.6 신뢰할 수 없고 취약한 테스트 ...................................................................................... 200<br />

7.6.1 누가 이 테스트를 작성하는가? .......................................................................... 201<br />

7.6.2 얼마나 오래 걸릴까? ....................................................................................... 202<br />

7.6.3 엄청난 적체 .................................................................................................. 203<br />

7.6.4 메타버전 ...................................................................................................... 204<br />

7.7 스토리가 아닌 테스트 여정 .......................................................................................... 204<br />

7.8 우리를 구할 소비자 주도 테스트 ................................................................................... 205<br />

7.8.1 팩트 ............................................................................................................ 207<br />

7.8.2 대화에 관하여 ............................................................................................... 208<br />

7.9 엔드 투 엔드 테스트를 사용해야 하는가? ....................................................................... 209<br />

7.10 출시 후의 테스팅 ....................................................................................................... 209<br />

7.10.1 배포를 릴리스와 분리하기 ............................................................................... 210<br />

7.10.2 카나리아 릴리스 ............................................................................................ 211<br />

7.10.3 MTBF보다 MTTR? ....................................................................................... 212<br />

7.11 교차기능 테스트 ........................................................................................................ 213<br />

7.11.1 성능 테스트 .................................................................................................. 215<br />

7.12 마치며 .................................................................................................................... 216<br />

CHAPTER 8 모니터링<br />

8.1 단일 서비스, 단일 서버 ............................................................................................... 218<br />

8.2 단일 서비스, 다수 서버 ............................................................................................... 219<br />

8.3 다수 서비스, 다수 서버 ............................................................................................... 220<br />

8.4 로그, 로그, 더 많은 로그... ......................................................................................... 221<br />

8.5 다수 서비스 간의 측정지표 추적 ................................................................................... 222<br />

21


CONTENTS<br />

8.6 서비스 측정지표 ........................................................................................................ 223<br />

8.7 합성 모니터링 ........................................................................................................... 224<br />

8.7.1 유의적 모니터링 구현하기 ............................................................................... 225<br />

8.8 상관관계 ID ............................................................................................................. 226<br />

8.9 전파 ....................................................................................................................... 229<br />

8.10 표준화 .................................................................................................................... 229<br />

8.11 관객 고려하기 ........................................................................................................... 230<br />

8.12 앞으로 .................................................................................................................... 231<br />

8.13 마치며 .................................................................................................................... 232<br />

CHAPTER 9 보안<br />

9.1 인증과 권한부여 ........................................................................................................ 235<br />

9.1.1 일반적인 SSO 구현체 .................................................................................... 236<br />

9.1.2 싱글 사인온 게이트웨이 .................................................................................. 237<br />

9.1.3 세분화된 권한 부여 ........................................................................................ 239<br />

9.2 서비스 대 서비스 인증과 권한부여 ................................................................................ 240<br />

9.2.1 경계 안의 모든 것 허용하기 ............................................................................. 240<br />

9.2.2 HTTP(S) 기본 인증 ........................................................................................ 241<br />

9.2.3 SAML 또는 OpenID Connect 사용하기 .......................................................... 242<br />

9.2.4 클라이언트 인증서 ......................................................................................... 243<br />

9.2.5 HTTP 기반의 HMAC .................................................................................... 243<br />

9.2.6 API 키 ......................................................................................................... 245<br />

9.2.7 대리인 문제 .................................................................................................. 246<br />

9.3 보관 중인 데이터 보호하기 .......................................................................................... 248<br />

9.3.1 잘 알려진 것을 사용하라 ................................................................................. 248<br />

9.3.2 키가 전부다 .................................................................................................. 249<br />

9.3.3 암호화 대상 정하기 ........................................................................................ 250<br />

22


9.3.4 요구형 복호화 ............................................................................................... 250<br />

9.3.5 백업 암호화하기 ............................................................................................ 250<br />

9.4 심층 방어 ................................................................................................................ 251<br />

9.4.1 방화벽 ......................................................................................................... 251<br />

9.4.2 로깅 ............................................................................................................ 251<br />

9.4.3 침입 탐지와 방지 시스템 ................................................................................. 252<br />

9.4.4 네트워크 분리(망 분리) ................................................................................... 252<br />

9.4.5 운영 체제 ..................................................................................................... 252<br />

9.5 시범 예제 ................................................................................................................ 253<br />

9.6 절약하라 ................................................................................................................. 256<br />

9.7 인적 요소 ................................................................................................................ 257<br />

9.8 황금률 .................................................................................................................... 257<br />

9.9 보안 탑재 ................................................................................................................ 258<br />

9.10 외부 검증 ................................................................................................................ 259<br />

9.11 마치며 .................................................................................................................... 259<br />

CHAPTER 10 콘웨이의 법칙과 시스템 <strong>설계</strong><br />

10.1 증거 ...................................................................................................................... 262<br />

10.1.1 느슨히 결합된 조직과 강력히 결합된 조직 ...................................................... 262<br />

10.1.2 윈도우 비스타 ........................................................................................... 262<br />

10.2 넷플릭스와 아마존 ................................................................................................... 263<br />

10.3 이것으로 무엇을 할 수 있을까? .................................................................................. 263<br />

10.4 의사소통 경로 적응 .................................................................................................. 263<br />

10.5 서비스 소유권 ......................................................................................................... 265<br />

10.6 공유 서비스의 추진 .................................................................................................. 265<br />

10.6.1 분리의 어려움 ........................................................................................... 266<br />

10.6.2 제품 특징 팀 ............................................................................................. 266<br />

23


CONTENTS<br />

10.6.3 전달 병목점 .............................................................................................. 267<br />

10.7 내부 오픈 소스 ........................................................................................................ 267<br />

10.7.1 관리인의 역할 ........................................................................................... 268<br />

10.7.2 성숙도 ..................................................................................................... 269<br />

10.7.3 도구 ........................................................................................................ 269<br />

10.8 경계가 있는 콘텍스트와 팀 구조 ................................................................................. 269<br />

10.9 방치된 서비스 ......................................................................................................... 270<br />

10.10 사례 연구: RealEstate.com.au ................................................................................ 270<br />

10.11 콘웨이의 역법칙 ...................................................................................................... 272<br />

10.12 사람 ...................................................................................................................... 273<br />

10.13 마치며 ................................................................................................................... 274<br />

CHAPTER 11 대규모 <strong>마이크로서비스</strong><br />

11.1 장애는 어디에서나 발생한다 ...................................................................................... 275<br />

11.2 얼마나 많아야 너무 많은 건가? .................................................................................. 276<br />

11.3 기능 분해 ............................................................................................................... 278<br />

11.4 <strong>아키텍처</strong> 안전 조치 .................................................................................................. 279<br />

11.5 안티프래질 조직 ...................................................................................................... 281<br />

11.5.1 타임아웃 .................................................................................................. 283<br />

11.5.2 회로 차단기 .............................................................................................. 283<br />

11.5.3 격벽 ........................................................................................................ 285<br />

11.5.4 격리 ........................................................................................................ 287<br />

11.6 멱등성 ................................................................................................................... 287<br />

11.7 확장 ...................................................................................................................... 289<br />

11.7.1 더 크게 만들기 .......................................................................................... 289<br />

11.7.2 작업부하 나누기 ........................................................................................ 289<br />

11.7.3 위험 <strong>분산</strong> ................................................................................................. 290<br />

24


11.7.4 부하 <strong>분산</strong> ................................................................................................. 291<br />

11.7.5 작업자 기반 시스템 .................................................................................... 293<br />

11.7.6 다시 시작하기 ........................................................................................... 294<br />

11.8 데이터베이스 확장 ................................................................................................... 295<br />

11.8.1 서비스의 가용성과 데이터의 내구성 .............................................................. 295<br />

11.8.2 읽기용 확장 .............................................................................................. 296<br />

11.8.3 쓰기용 확장 .............................................................................................. 297<br />

11.8.4 공유 데이터베이스 인프라스트럭처 ............................................................... 298<br />

11.8.5 CQRS .................................................................................................... 298<br />

11.9 캐싱 ...................................................................................................................... 299<br />

11.9.1 클라이언트 측, 프록시, 그리고 서버 측 캐싱 .................................................... 300<br />

11.9.2 HTTP의 캐싱 ........................................................................................... 301<br />

11.9.3 쓰기용 캐싱 .............................................................................................. 302<br />

11.9.4 회복성을 위한 캐싱 .................................................................................... 303<br />

11.9.5 원본 감추기 .............................................................................................. 303<br />

11.9.6 단순화하라 ............................................................................................... 304<br />

11.9.7 캐시 중독: 경계할 일화 ............................................................................... 305<br />

11.10 자동 확장 ............................................................................................................... 306<br />

11.11 CAP 정리 ............................................................................................................. 307<br />

11.11.1 일관성 희생하기 ........................................................................................ 309<br />

11.11.2 가용성 희생하기 ........................................................................................ 309<br />

11.11.3 분할용인 희생하기? ................................................................................... 310<br />

11.11.4 AP 또는 CP? ........................................................................................... 311<br />

11.11.5 양자택일이 아니다 ..................................................................................... 311<br />

11.11.6 그리고 현실세계 ........................................................................................ 312<br />

11.12 서비스 발견 ............................................................................................................ 312<br />

11.12.1 DNS ....................................................................................................... 313<br />

11.13 동적 서비스 레지스트리 ............................................................................................ 315<br />

25


CONTENTS<br />

11.13.1 주키퍼 ..................................................................................................... 315<br />

11.13.2 칸슬 ........................................................................................................ 316<br />

11.13.3 유레카 ..................................................................................................... 317<br />

11.13.4 직접 만들기 .............................................................................................. 318<br />

11.13.5 사람을 잊지 마라! ...................................................................................... 318<br />

11.14 문서화 서비스 ......................................................................................................... 318<br />

11.14.1 스웨거 ..................................................................................................... 319<br />

11.14.2 HAL과 HAL 브라우저 ................................................................................ 319<br />

11.15 자기 기술 시스템 ..................................................................................................... 320<br />

11.16 마치며 ................................................................................................................... 321<br />

CHAPTER 12 종합 정리<br />

12.1 <strong>마이크로서비스</strong>의 원칙 ............................................................................................. 323<br />

12.1.1 비즈니스 개념에 따른 모델 .......................................................................... 324<br />

12.1.2 자동화 문화의 적용 .................................................................................... 324<br />

12.1.3 내부 세부 구현의 은폐 ................................................................................ 325<br />

12.1.4 모든 것을 분권화 ....................................................................................... 325<br />

12.1.5 독립적인 배포 ........................................................................................... 326<br />

12.1.6 장애 격리 ................................................................................................. 327<br />

12.1.7 매우 식별 가능한 ....................................................................................... 327<br />

12.2 언제 <strong>마이크로서비스</strong>를 사용하지 않아야 하는가? .......................................................... 327<br />

12.3 이 책을 마치며 ........................................................................................................ 328<br />

찾아보기 ................................................................................................................................................... 330<br />

26


CHAPTER 1<br />

<strong>마이크로서비스</strong><br />

우리 IT 종사자들은 시스템 <strong>구축</strong>을 위한 더 나은 방법을 끊임없이 모색해왔다. 과거로부터 배웠<br />

고, 새로운 기술에 적용했으며, 고객과 개발자 모두 만족하는 IT 시스템을 만들기 위해 신기술<br />

들이 업체에서 얼마나 다양한 방식으로 운영되는지 관찰했다.<br />

에릭 에반스 Eric Evans 의 『도메인 주도 <strong>설계</strong>』(위키북스, 2011 ) 1 는 실세계를 코드로 표현하는 일<br />

이 얼마나 중요한지 이해하는 데 도움을 주었으며, 시스템을 모델링하는 더 나은 방법을 보여<br />

주었다. 2 지속적 배포 continuous delivery 는 체크인 check-in 한 모든 것을 릴리스 후보로 대해야 한다<br />

는 생각을 우리에게 주입시키고, 어떻게 하면 더 효과적이면서도 효율적으로 소프트웨어를 양<br />

산 3 할 수 있는지 보여주었다. 또한 웹 동작 원리를 이해함으로써 머신 machine 들이 통신할 수 있<br />

는 더 나은 방법을 개발하게 되었다. 앨리스테어 콕번 Alistair Cockburn 의 육각형 <strong>아키텍처</strong> hexagonal<br />

architecture<br />

개념 4 은 우리가 비즈니스 로직이 숨을 수 있는 계층형 <strong>아키텍처</strong>로부터 멀어지도록 안<br />

내했다. 가상화 플랫폼은 머신을 원하는 대로 프로비저닝 provisioning5 하고 규모를 조절하게 해주<br />

1 『Domain-Driven Design』(Addison-Wesley)<br />

2 옮긴이_ 도메인 주도 <strong>설계</strong>(DDD)는 복잡한 요구 사항의 소프트웨어를 위한 개발 방법론으로, 도메인 모델링과 진화하는 모델 구현을 기<br />

반으로 한다. 소프트웨어 <strong>설계</strong>에 있어 거의 필독서가 된 이 책과 저자에 대해 관심을 가지길 권한다.<br />

3 옮긴이_ 패키지를 운영 환경 또는 고객에게 배포하는 것<br />

4 옮긴이_ Ports and Adapters 패턴이라고도 한다. 외부 세계와 인터페이스를 담당하는 프레임워크(Ports and Adapters) 계층, 비<br />

즈니스 로직의 애플리케이션 계층, 도메인 계층으로 분리하여 서비스의 이식성, 테스트 가용성, 변화를 최소화할 수 있는 <strong>아키텍처</strong>다.<br />

http://goo.gl/Vzma를 참고하라.<br />

5 옮긴이_ 가상화된 인프라스트럭처 자원(네트워크, 가상 머신, OS, 소프트웨어, 설정 등)을 사용자 또는 비즈니스 요구 사항에 맞게 할당,<br />

배치, 배포, 구성하여 사용할 수 있도록 하는 일련의 작업. https://goo.gl/ZPasJQ를 참고하라.<br />

27


었다. 그리고 인프라스트럭처 자동화 infrastructure automation 는 머신을 확장 scaling 하는 방법 6 을 제공<br />

했다. 아마존과 구글 같은 몇몇 성공한 대기업은 서비스를 만든 작은 팀에서 그 서비스의 수명주<br />

기를 관리하는 것이 옳다는 관점을 지지했다. 최근 넷플릭스 Netflix 는 불과 십 년 전까지만 해도<br />

이해하기 어려웠던 확장 가능한 안티프래질 시스템 antifragile system 을 <strong>구축</strong>하는 방법을 공유했다. 7<br />

도메인 주도 <strong>설계</strong>, 지속적 배포, 주문형 가상화 on-demand virtualization , 인프라스트럭처 자동화, 작<br />

고 자율적인 팀, 대규모 시스템 system at scale 등의 분위기에 편승한 <strong>마이크로서비스</strong>는 실사용을<br />

기반으로 하나의 대세 내지는 패턴으로 부상했다. 현재의 <strong>마이크로서비스</strong>는 사라져버린 과거의<br />

유물 위에 세워졌다. 필자는 이 책을 통해 <strong>마이크로서비스</strong>를 <strong>구축</strong>하고 관리하고 발전시키는 방<br />

법을 이해할 수 있도록 과거 이야기부터 시작할 것이다.<br />

많은 조직은 세분화된 <strong>마이크로서비스</strong> <strong>아키텍처</strong>를 포용하는 과정에서 소프트웨어를 더 빨리 배<br />

포하고 새로운 기술도 흡수할 수 있다는 것을 발견했다. <strong>마이크로서비스</strong>는 우리 모두에게 영향<br />

을 미칠 피할 수 없는 변화에 신속히 대응할 수 있게 해주며, 다양한 결정과 판단을 내릴 수 있는<br />

자유를 부여한다.<br />

1.1 <strong>마이크로서비스</strong>란<br />

<strong>마이크로서비스</strong>란 작고 자율적으로 협업하는 서비스를 의미한다. 이 정의를 구체적으로 해부<br />

하고 <strong>마이크로서비스</strong>를 차별화하는 특성에 대해 살펴보자.<br />

1.1.1 작고, 한 가지 일을 잘하는 데 주력<br />

코드베이스 codebase8 는 새로운 기능을 추가하면서 성장한다. 하지만 시간이 지날수록 매우 방대해<br />

져서 어디를 변경해야 할지 파악하기 어려워진다. 명확하고 모듈화된 모놀리식 monolithic 코드베이<br />

6 옮긴이_ 스케일 업(다운)이라 불리는 수직 확장은 머신 리소스(CPU, 메모리, 스토리지 등)를 추가하는 것이며, 스케일 아웃(인)이라 불<br />

리는 수평 확장은 <strong>시스템의</strong> 노드, 머신, 애플리케이션 등을 추가하는 것이다. https://goo.gl/lYqGn0을 참고하라.<br />

7 옮긴이_ ‘안티프래질’은 ‘블랙스완’으로 유명한 작가 나심 니콜라스 탈레브(Nassim Nicholas Taleb)가 경제학 법칙을 위해 소개한 용<br />

어로, 충격에 강하거나(robust) 탄력적(resilient)이라는 의미보다는 충격으로 인해 더 단단해지고 강해진다는 개념에 가깝다.<br />

8 옮긴이_ 코드베이스란 소프트웨어 시스템, 애플리케이션, 컴포넌트를 빌드하는 데 사용되는 코드의 전체 집합으로, 일반적으로 작성한 코<br />

드 파일을 의미한다. 여기서는 원문 의미를 살려 코드베이스로 표기한다.<br />

28 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


스를 추구하더라도 중간 경계의 어딘가가 빈번히 무너지기 시작하고, 버그를 고치거나 어려운<br />

구현을 하는 과정에서 유사한 기능과 연관된 코드가 곳곳으로 퍼져나간다.<br />

모놀리식 시스템 9 에서 우리는 코드를 더 응집 cohesive10 하고, 추상화 또는 모듈화하면서 앞에서<br />

언급한 위협에 대항한다. 응집력, 즉 관련된 코드들을 함께 그룹화하려는 힘은 <strong>마이크로서비스</strong><br />

의 중요한 개념이다. 로버트 C. 마틴 Robert C. Martin 은 단일 책임 원칙 Single Responsibility Principle11 에<br />

서 다음과 같이 강조했다. “같은 이유로 변경되는 것들은 한데 모으고, 서로 다른 이유로 변경<br />

되는 것들은 분리하라.”<br />

<strong>마이크로서비스</strong>는 독립적인 서비스에 대해 동일한 접근 방식을 취한다. 주어진 기능과 관련 코<br />

드들이 명확히 제자리에 있도록 하면서 서비스 경계를 비즈니스 경계에 일치시킨다. 그리고 이<br />

서비스의 명확한 경계를 지키면서 서비스가 지나치게 커지는(모든 골칫거리를 만들어내는) 것<br />

에 대한 유혹을 회피한다.<br />

필자는 “얼마나 작아야 작은 것인가?”라는 질문을 자주 받는다. 일부 프로그래밍 언어는 다<br />

른 언어보다 표현력이 좋아서 훨씬 더 적은 줄 수로도 더 많은 일을 할 수 있다. 따라서 코드 줄<br />

수를 기준으로 제시하는 것은 문제가 있다. 또한 우리는 그 자체가 수많은 코드로 구성된 복<br />

합적인 종속성에 대해서도 고려해야 한다. 게다가 우리 도메인 영역 중 일부는 합당한 이유<br />

로 복잡해진 만큼 더 많은 코드가 필요할 수 있다. 실제로 호주의 부동산 매매정보 사이트인<br />

RealEstate.com.au의 존 이브스 Jon Eaves 는 경험적으로 ‘<strong>마이크로서비스</strong>란 2주 안에 재작성될<br />

수 있는 것’이라고 특정한다.<br />

<strong>마이크로서비스</strong>의 크기에 대해 필자가 말할 수 있는 다소 진부한 다른 답변은 ‘충분히 작아서<br />

더 이상 작아질 수 없는 크기’다. 필자는 컨퍼런스에서 발표할 때 ‘지나치게 큰 시스템을 관리<br />

중이며 이를 작게 세분화하기 원하는 사람’이 있는지 매번 물어보는데, 거의 모든 사람이 손을<br />

든다. 우리는 어떤 것이 지나치게 큰 것인지에 대해서는 매우 잘 인지하고 있는 것 같다. 따라<br />

서 코드가 너무 크다고 느껴지지 않는 한 아마 아직까지는 충분히 작다고 할 수 있다.<br />

9 옮긴이_ 데이터 입력, 출력, 프로세싱, 에러 처리, UI(사용자 인터페이스)와 같은 구분된 기능들이 분리되어 있지 않고 혼합된 구조의 시<br />

스템을 말한다.<br />

10 옮긴이_ 3.2.2절 ‘강한 응집력’ 참조<br />

11 http://bit.ly/1zOFMxl<br />

1장 <strong>마이크로서비스</strong><br />

29


얼마나 작은지에 대한 답변을 하기 위해서는 서비스가 팀 구조와 서로 얼마나 적절하게 배치되<br />

어 있는지 아는 게 중요하다. 만약 코드베이스가 한 팀이 감당하기에 너무 크다면 작게 나누는<br />

것이 당연하다. 조직의 배치에 대해서는 1.2.5절에서 더 이야기하자.<br />

얼마나 작은 것이 충분히 작은 것인지에 관해 논할 때 필자는 다음과 같은 생각을 한다. 서비스<br />

가 작아질수록 <strong>마이크로서비스</strong> <strong>아키텍처</strong>의 혜택과 단점은 더 극대화되며, 서비스를 작게 만들<br />

면 만들수록 상호의존성에 의한 문제는 줄어든다. 더 많은 구성 요소를 추가해서 발생하는 몇몇<br />

복잡성에 대해서는 이 책 전반에 걸쳐 살펴볼 것이다. 이러한 복잡성을 다루는 데 능숙해질수<br />

록 더 작은 서비스를 추구할 수 있다.<br />

1.1.2 자율성<br />

<strong>마이크로서비스</strong>는 분리된 개체다. 이것은 PaaS Platform as a Service: 서비스로서의 플랫폼12 상의 격리된 서<br />

비스이거나 운영체제 상의 프로세스가 될 수 있다. 우리는 여러 가지 서비스를 동일 머신에 넣는<br />

것을 피하려 한다. 다만 요즘 세상에 머신의 정의가 매우 모호하다는 점은 짚고 넘어갈 필요가<br />

있다. 나중에 논의하겠지만 이러한 격리가 약간의 부담을 주더라도 결과적으로 얻어지는 단순<br />

화를 통해 <strong>분산</strong> 시스템을 더 쉽게 추론할 수 있고 더 새로운 기술들을 통해 이러한 배포 형태와<br />

관련한 많은 어려움을 극복할 수 있다.<br />

서비스 간의 <strong>분산</strong>도를 높이고 서비스 간에 밀접하게 연결되어 생기는 문제점을 줄이기 위해 서<br />

비스 사이의 모든 통신은 네트워크 호출을 통해 이루어진다. 이 서비스들은 서로 독립적으로 변<br />

경될 수 있어야 하고, 소비자 consumer13 를 변경할 필요 없이 독립적으로 배포될 수 있어야 한다.<br />

이때 우리는 서비스가 무엇을 외부에 드러내고 무엇을 내부에 두어야 하는지 고민해야 한다. 너<br />

무 많이 외부에 드러내면 소비자 서비스가 내부 구현과 엮이게 된다. 이 경우 서비스를 변경할<br />

때 소비자와 조율할 게 그만큼 많아지므로 결과적으로 자율성이 줄어든다.<br />

우리 서비스는 애플리케이션 프로그래밍 인터페이스 application programming interface (API)를 공개하<br />

며, 이 API를 통해 상호 협업하는 서비스들과 통신한다. 우리는 기술이 소비자와 결합되지 않<br />

도록 어떤 기술이 적절한지 고민해야 한다. 이것은 다양한 기술을 선택할 수 있도록 기술 중립적<br />

12 옮긴이_ 개발을 위한 플랫폼 <strong>구축</strong> 없이도 필요한 개발 요소들을 웹에서 쉽게 빌려 쓸 수 있게 하는 모델<br />

13 옮긴이_ 여기서는 서비스를 호출하는 다른 서비스가 될 수 있다.<br />

30 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


인 technology-agnostic API를 선택함을 의미할 수 있다. 이 책에서는 구현 방식에 영향받지 않는 좋<br />

은 API의 중요성에 관해 자주 언급할 것이다.<br />

결합을 없애지 decoupling 않고는 모든 것이 소용없어진다. 황금률은 ‘다른 변경 없이 특정 서비스<br />

만 변경하고 배포할 수 있는가?’다.<br />

서비스를 잘 분리하려면 서비스를 올바르게 모델링하고 API를 제대로 만들어야 한다. 그 방법<br />

에 대해서는 앞으로 많이 이야기하겠다.<br />

1.2 주요 혜택<br />

<strong>마이크로서비스</strong>가 제공하는 혜택은 많으면서도 다양하다. 이러한 혜택 대부분은 다른 <strong>분산</strong> 시<br />

스템도 제공하지만, <strong>마이크로서비스</strong>의 경우 <strong>분산</strong> 시스템과 서비스 지향 <strong>아키텍처</strong> service-oriented<br />

architecture 의 개념을 더 깊이 내포하는 만큼 훨씬 더 많은 혜택을 누릴 수 있다.<br />

1.2.1 기술 이기종성<br />

다수의 협업 서비스로 구성된 시스템에서는 각 서비스가 다른 기술을 사용하도록 결정할 수 있<br />

다. 이는 결국 최소한의 공통점만을 지닌 표준화된, 만능의 접근 방식을 선택하기보다 각 작업에<br />

적합한 도구를 선택하게 해준다.<br />

시스템 특정 부분의 성능을 높이려 할 때, 요구되는 성능 수준을 만족하는 데 유리한 다른 기술<br />

스택을 고려해야 할 수도 있고 변환할 데이터를 어떻게 저장할지 결정해야 할 수도 있다. 예를<br />

들어 소셜 네트워크의 경우에는 소셜 그래프의 높은 상호 연결성을 반영하기 위해 사용자 상호<br />

작용은 그래프 지향 데이터베이스 graph-oriented database 에, 사용자 게시물은 문서 지향 데이터 저장<br />

소 documented-oriented data storage 에 저장할 수 있다. 즉, [그림 1-1]과 같은 이기종 <strong>아키텍처</strong>가 생겨<br />

난다.<br />

1장 <strong>마이크로서비스</strong><br />

31


그림 1-1 다양한 기술을 더 쉽게 포용하도록 만드는 <strong>마이크로서비스</strong> 1415<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

14 15<br />

<br />

<strong>마이크로서비스</strong>를 통해 기술을 더 신속히 적용할 수 있고, 개선된 새로운 기능들이 어떻게 도움<br />

이 될지 살펴볼 수 있다. 새로운 기술을 시험하고 적용하는 과정에서 최대 걸림돌은 새로운 기<br />

술을 도입했을 때 결국에는 잘 맞지 않을 수 있다는 위험이다. 모놀리식 애플리케이션에서 새로<br />

운 프로그래밍 언어, 데이터베이스 또는 프레임워크를 시도하면 그 변경은 시스템에 큰 영향을<br />

미칠 것이다. 하지만 다양한 독립 서비스로 구성된 시스템에는 새로운 기술 분야를 시험해볼 만<br />

한 곳이 많다. 혹시 잘못될 때 제한할 수 있는 방법이 있다면 리스크가 가장 낮은 서비스를 선택<br />

해서 그곳에 새로운 기술을 사용해볼 수 있다.<br />

물론 여러 기술을 함께 사용하면 문제가 전혀 없을 수는 없다. 몇몇 기업은 프로그래밍 언어 선택<br />

Java Virtual Machine<br />

에 일부 제한을 걸어둔다. 예를 들어 넷플릭스와 트위터는 대부분 자바 가상 머신<br />

(JVM)을 플랫폼으로 사용하는데, 이는 JVM의 신뢰성과 성능을 매우 잘 이해하고 있기 때문이<br />

다. 또한 그들은 대규모 <strong>시스템의</strong> 운영을 더 쉽게 만드는 JVM용 라이브러리와 도구를 개발하<br />

고 있지만 자바 기반이 아닌 서비스와 클라이언트로는 어려움이 더 많다. 그렇다고 해서 트위터<br />

나 넷플릭스가 한 가지 기술 스택을 모든 작업에 사용하는 것은 아니다. 다른 기술들의 병행 사<br />

용에 우려되는 또 다른 요소는 (서비스의) 크기다. 만약 실제로 2주 안에 <strong>마이크로서비스</strong>를 재<br />

작성할 수 있다면 새로운 기술을 적용하는 데 따른 리스크를 완화할 수 있을 것이다.<br />

이 책을 통해 알게 되겠지만 <strong>마이크로서비스</strong>와 관련된 다른 많은 사항과 마찬가지로 올바른 균<br />

형을 찾는 것이 최선이다. 진화적 <strong>아키텍처</strong>를 주로 다루는 2장에서는 기술을 선택하는 방법을 논<br />

14 옮긴이_ 그래프 DB는 노드, 에지, 프로퍼티에 대한 시맨틱 검색을 위해 그래프 구조를 사용하는 데이터베이스 시스템으로 Neo4j,<br />

Titan, OrientDB 등이 있다.<br />

15 옮긴이_ Blob(Binary Large Object) 저장소는 이미지, 오디오, 멀티미디어 및 파일을 저장하는 데 사용하는 저장 시스템이다. AWS<br />

S3 또는 Azure Blob 스토리지 등이 있다.<br />

32 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


의하고, 시스템 통합을 다루는 4장에서는 서비스 간의 지나친 결합 없이 독립적으로 기술을 진<br />

화시키는 방법을 배울 것이다.<br />

1.2.2 회복성<br />

회복 공학 resilience engineering 의 핵심 개념은 ‘격벽 bulkhead ’ 16 이다. 즉, 한 <strong>시스템의</strong> 컴포넌트에 장<br />

애가 발생하더라도 그 장애가 전파되지 않는다면 해당 문제를 격리하고 나머지 시스템을 계속<br />

작동시킬 수 있다. 서비스의 경계야말로 명확한 격벽인 셈이다. 모놀리식 서비스에서는 한 서비<br />

스가 고장나면 모든 것이 작동을 멈춘다. 모놀리식 시스템은 장애 가능성을 낮추기 위해 수많은<br />

머신 상에서 실행되어야 하지만, <strong>마이크로서비스</strong>에서는 서비스의 전체 장애를 차단하고 기능을<br />

적절히 저하 degrade 시키는 시스템을 <strong>구축</strong>할 수 있다. 17<br />

하지만 주의해야 할 점도 있다. <strong>마이크로서비스</strong> 시스템이 향상된 회복력을 적절히 수용할 수 있<br />

도록 <strong>분산</strong> 시스템이 마주한 새로운 장애 요인들을 이해해야 한다. 네트워크도 머신처럼 장애가<br />

발생할 수 있는 만큼 이것을 다루는 방법을 이해해야 하며, 소프트웨어의 최종 사용자에게 어떤<br />

영향을 미치는지도 알아야 한다.<br />

회복력과 장애 형태를 더 잘 처리하는 방법에 대해서는 11장에서 자세히 이야기하겠다.<br />

1.2.3 확장성<br />

하나의 큰 모놀리식 서비스에서는 항상 모든 것을 함께 확장해야 한다. 만약 전체 시스템에서 작<br />

은 한 부분만 성능이 떨어지는데, 해당 동작이 거대한 모놀리식 애플리케이션에 묶여 있다면 전<br />

체를 한 덩어리처럼 확장해야 한다. 그러나 만약 작은 서비스들로 구성되어 있다면 필요한 서비<br />

스만 확장할 수 있다. 또한 다음 [그림 1-2]처럼 나머지 서비스를 더 작고 낮은 사양의 하드웨<br />

어에서 실행할 수 있다.<br />

16 옮긴이_ 선박의 방을 막는 칸막이벽으로, 장애의 전파를 막는 용도로 사용된다.<br />

17 옮긴이_ 결함 감내 시스템(장애 허용 시스템, fault tolerant system)은 일부 장치나 서브시스템에 고장이나 오작동이 나타나면 시스<br />

템의 성능과 기능을 축소 구성하여 정지하지 않고도 동작을 유지하는 방식을 사용하고 있는데, 이 방식을 단계별 성능 저하(graceful<br />

degradation)라고 한다.<br />

1장 <strong>마이크로서비스</strong><br />

33


그림 1-2 <strong>마이크로서비스</strong>로 필요한 만큼만 확장 가능<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

온라인 패션몰인 길트 Gilt 는 정확히 이런 이유로 <strong>마이크로서비스</strong>를 도입했다. 2007년부터 2009<br />

년까지 모놀리식 레일즈 애플리케이션 18 으로 작성된 길트 시스템은 유입되는 부하를 충분히 처<br />

리할 수 없었다. 하지만 <strong>시스템의</strong> 코어 부분을 분리하면서부터는 급등하는 트래픽을 더 잘 처리<br />

할 수 있게 되었다. 현재 450개 이상의 <strong>마이크로서비스</strong>가 분리된 많은 머신에서 동작 중이다.<br />

아마존 웹 서비스 Amazon Web Service (AWS)에서 제공하는 것과 같은 주문형 프로비저닝 시스템<br />

on-demand provisioning system 을 도입하면 필요한 곳에 이 주문형 확장 기술을 적용할 수 있다. 이렇<br />

게 필요에 따라 확장하는 것이 비용을 더욱 효과적으로 쓸 수 있게 해주지만 미리 모든 걸 다 예<br />

상해서 <strong>아키텍처</strong>로만 해결하려 할 때 바로 비용절감으로 이어지는 경우는 드물다.<br />

1.2.4 배포 용이성<br />

무려 백만 줄에 달하는 모놀리식 애플리케이션에서는 한 줄만 수정하더라도 해당 변경을 릴리<br />

스하기 위해 전체 애플리케이션을 배포해야 한다. 이는 막대한 영향을 끼치는 아주 위험한 배포<br />

가 될 수 있다. 실제로는 이러한 걱정으로 위험도가 높은 배포는 잘 안 하게 된다. 그렇기 때문에<br />

18 옮긴이_ 길트는 2007년 Ruby on Rails로 작성한 모놀리식 애플리케이션을 2009년 자바로 작성된 10개의 <strong>마이크로서비스</strong>로 변환<br />

했고, 2011년에 스칼라를 적용했다. 2014년 Node.js를 도입하여 수백 개 이상의 <strong>마이크로서비스</strong>를 운영하고 있다.<br />

34 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


CHAPTER 5<br />

모놀리스 분해하기<br />

우리는 좋은 서비스의 모습과 더 작은 서버가 더 나은 이유에 대해 논의했다. 그리고 <strong>시스템의</strong><br />

디자인을 진화시키는 능력의 중요성에 대해서도 이야기했다. 하지만 이러한 패턴을 따르지 않는<br />

거대한 코드베이스가 이미 있다는 사실을 어떻게 다뤄야 할까? 우리는 한번에 엄청난 분량의<br />

코드를 재작성하지 않고 어떻게 이러한 모놀리식 애플리케이션의 분해를 시작할 수 있을까?<br />

모놀리스 monolith1 는 시간이 흐르면서 자라나고, 빠른 속도로 새로운 기능과 코드 라인을 요구하<br />

며, 머지않아 조직 내 사람들이 건드리거나 바꾸기를 두려워하는 거대하고 무서운 존재가 된다.<br />

그러나 전혀 희망이 없는 것은 아니다. 우리는 자유자재로 다룰 수 있는 올바른 도구를 통해 이<br />

야수를 없앨 수 있다.<br />

5.1 접합부가 중요하다<br />

3장에서 우리는 응집력이 높고 느슨히 결합되는 서비스를 원한다고 이야기했다. 하지만 모놀<br />

리스의 문제는 대개 이와는 너무도 정반대라는 것이다. 응집력을 지향하며 함께 변경될 가능성<br />

이 높은 것들을 함께 두기 보다는 관련 없는 모든 종류의 코드를 가져와 서로 붙여놓는다. 느슨<br />

한 결합은 아예 존재하지도 않는다. 코드 한 줄 정도는 아주 쉽게 변경할 수 있겠지만, 모놀리<br />

1 옮긴이_ 모놀리스는 단일체라는 의미지만, 이 장에서는 모놀리식 시스템, 서비스 및 애플리케이션을 뜻한다.<br />

125


스의 나머지 코드에 영향을 주지 않고 배포할 수는 없다. 따라서 반드시 전체 시스템을 재배포<br />

해야 한다.<br />

마이클 페더스의 『레거시 코드 활용 전략』(에이콘출판사, 2008 ) 2 에서는 접합부 seam 의 개념을<br />

‘코드베이스의 나머지 부분에 영향을 주지 않는 격리된 코드 부분’이라고 정의한다. 우리는 접합<br />

부를 찾아내기 원한다. 그러나 코드베이스를 정리할 목적으로 접합부를 찾기보다는 서비스의 경<br />

계가 될 수 있는 접합부를 발견하기 원한다.<br />

그렇다면 무엇이 좋은 접합부를 만들까? 우리가 이전에 논의했던 것처럼 경계가 있는 콘텍스트<br />

bounded context 는 훌륭한 접합부를 만든다. 경계가 있는 콘텍스트의 정의가 조직 내의 응집력 있고<br />

느슨히 결합된 경계를 잘 표현하기 때문이다. 따라서 첫 번째 단계는 우리 코드에서 이 경계를 인<br />

식하는 것이다.<br />

대부분의 프로그래밍 언어는 유사한 코드를 그룹화하는 네임스페이스 개념을 제공한다. 자바의<br />

package 개념은 아주 적절한 예는 아니지만, 우리가 필요로 하는 많은 점을 시사한다. 다른 대<br />

부분의 주류 언어도 package와 유사한 개념을 내장하고 있지만 자바스크립트는 논란의 여지가<br />

있으니 예외로 하자.<br />

5.2 뮤직코퍼레이션 분해하기<br />

뮤직코퍼레이션 온라인 <strong>시스템의</strong> 아주 많은 행동양식 behavior 을 구성하는 거대한 모놀리식 서비<br />

스 백엔드가 있다고 가정하자. 우선 3장에서 논의했듯이 우리 조직에 존재한다고 생각되는 상<br />

위 수준의 경계가 있는 콘텍스트를 인식해야 한다. 그러면 모놀리식 백엔드가 매핑하고 있는<br />

경계가 있는 콘텍스트를 이해하고 싶어질 것이다. 모놀리식 백엔드가 포함하고 있다고 생각되는<br />

4개의 콘텍스트를 초기에 파악했다고 하자.<br />

제품 목록<br />

판매하는 제품에 대한 모든 메타데이터<br />

재무<br />

계정, 결제, 환불 등의 보고<br />

2 『Working Effectively with Legacy Code』(Prentice Hall, 2004)<br />

126 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


창고<br />

고객 주문 발송 및 반품, 재고 수준 관리 등<br />

추천<br />

특허 출원 중이며 획기적인 우리의 추천 시스템으로 일반 연구소보다 박사 비율이 높은 팀이 매우 복잡한 코드로<br />

작성함<br />

처음 해야 할 일은 이 콘텍스트들을 대표하는 패키지를 생성하는 것이다. 그다음에는 기존 코드<br />

를 패키지로 이동시킨다. 현대적인 IDE에서 코드 이동은 리팩토링 기능을 통해 다른 작업 중에<br />

자동적이고 점진적으로 이뤄질 수 있다. 하지만 코드 이동에 따른 오류를 잡아내기 위해 여전히<br />

테스트가 필요하다. 특히 IDE가 리팩토링하는 데 더 까다로운 동적 타입 언어를 사용한다면 더<br />

욱 그렇다. 시간이 지나면서 우리는 잘 어울려 남아 있는 코드와 그렇지 못한 코드를 알아가기<br />

시작한다. 대개 끝까지 생존한 코드가 우리가 간과했을지 모를 경계가 있는 콘텍스트로 인식될<br />

수 있다!<br />

이 과정에서 우리는 패키지 간의 의존성을 분석할 수 있는 코드를 사용할 수 있다. 우리가 만든<br />

코드는 우리 조직을 대표해야 마땅하므로 경계가 있는 콘텍스트를 대표하는 패키지들은 실세계<br />

에서 도메인과 같은 방식으로 상호작용해야 한다. 예를 들어 스트럭처 101 Structure 1013 과 같은<br />

도구는 패키지 간의 의존성을 시각적으로 표현한다. 예를 들어 실제 조직에서는 창고부서가 재<br />

무부서에 전혀 의존성이 없지만 창고 패키지의 코드가 재무 패키지에 의존성이 있는 것처럼 뭔<br />

가 잘못된 것이 보이면 우리는 이 문제를 파악하고 해결할 수 있다.<br />

이 과정은 작은 코드베이스의 경우 반나절로 충분하지만, 수백만 라인의 코드를 처리하는 데는<br />

수주 또는 수개월이 걸릴 수 있다. 첫 번째 서비스를 분리하기 전에 모든 코드를 도메인에 따라<br />

나눠진 패키지들에 따라 정렬할 필요는 없으며, 그러한 노력을 우선 한 곳에 집중하는 것이 더<br />

가치 있을 것이다. 한번에 모든 것을 바꾸려는 빅뱅 big-bang 접근법을 취할 필요는 없고, 이 과정<br />

을 천천히 조금씩 진행되는 것으로 인식해야 한다. 그리고 우리에게는 이 분해 과정을 추적할<br />

수 있는 많은 도구가 있다.<br />

이제 접합부 주변으로 코드베이스의 구조를 변경했다. 다음 과정은 무엇일까?<br />

3 옮긴이_ 스트럭처 101은 애자일 <strong>아키텍처</strong> 개발 환경(Architecture Development Environment)으로, 코드베이스의 구조화를 돕기<br />

위해 다양한 IDE를 위한 플러그인을 제공한다. 자세한 내용은 https://structure101.com을 참고하라.<br />

5장 모놀리스 분해하기<br />

127


5.3 모놀리스를 분리하는 이유<br />

모놀리식 서비스 또는 애플리케이션을 더 작게 만들려는 결정은 좋은 출발점이다. 그러나 필자<br />

는 시스템을 조금씩 깎아내듯이 분리하기를 강력히 권고하고 싶다. 이러한 점진적 접근법을 통<br />

해 <strong>마이크로서비스</strong>를 더 잘 배울 수 있으며, 무언가 잘못된 경우(당신이 잘못한 경우에도!) 피<br />

해를 줄일 수 있다. 모놀리스를 대리석판 덩어리로 생각해보자. 이것을 한번에 깎을 수도 있지<br />

만 대개 실패할 것이다. 점진적으로 조금씩 깎아내는 것이 훨씬 합리적이다.<br />

모놀리스를 한 번에 하나씩 분해하기로 했다면 어디서부터 시작해야 할까? 우리에게는 지금<br />

접합부가 있지만 어떤 것부터 떼어내야 할까? 코드베이스를 분리했을 때 가장 큰 혜택이 있는<br />

부분을 생각하는 것이 최선이다. 끌질을 잘할 수 있도록 안내하는 몇 가지 추진 동력을 생각해<br />

보자.<br />

5.3.1 변경의 속도<br />

아마도 우리는 재고 목록을 관리하는 과정에서 앞으로 발생할 변경으로 인한 부담을 알고 있을<br />

것이다. 따라서 지금 창고의 접합부를 서비스로 분리한다면, 그 접합부는 독립된 자율적 개체<br />

가 되어 더욱 신속하게 변경 가능하다.<br />

5.3.2 팀 구조<br />

뮤직코퍼레이션의 제품 출시 delivery 팀은 두 지역으로 나뉘어, 한 팀은 런던, 다른 팀은 하와이<br />

(몇몇 사람은 여기서 편안히 보낼 수 있겠지만!)에 있다. 만약 하와이 팀이 주로 작업하는 코<br />

드를 분리해서 모든 소유권을 가질 수 있다면 정말 좋을 것이다. 이 아이디어에 대해서는 10장<br />

에서 더 자세히 탐구하자.<br />

5.3.3 보안<br />

뮤직코퍼레이션은 보안 감사를 받았고, 민감한 정보의 보호를 강화하기로 결정했다. 현재는 재<br />

무 관련 코드에 대해 진행하고 있다. 만약 이 서비스를 분리한다면 개별 서비스를 모니터링할 수<br />

128 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


있고 데이터의 전송과 저장에 있어 추가적인 보호를 할 수 있다. 이러한 아이디어에 관해서는<br />

9장에서 자세히 살펴볼 것이다.<br />

5.3.4 기술<br />

추천 시스템을 담당하는 팀은 클로저 Clojure4 언어로 작성된 라이브러리를 이용하여 몇 가지 새<br />

로운 알고리즘을 개발해왔다. 그 팀은 알고리즘의 향상된 추천 기능을 통해 고객에게 혜택을<br />

줄 수 있다고 생각한다. 만약 추천 <strong>시스템의</strong> 코드를 분리해서 독립된 서비스로 만들 수 있다면<br />

그것을 테스트할 수 있는 다른 구현 방식을 쉽게 고려할 수 있다.<br />

5.4 뒤엉킨 의존성<br />

분리할 접합부 몇 개를 인식했을 때 고려할 또 다른 점은 그 코드가 <strong>시스템의</strong> 나머지 부분과 어<br />

떻게 엉켜져 있는가 하는 것이다. 우리는 가능한 한 종속성이 낮은 접합부를 추출하기 원한다.<br />

여러분이 발견한 다양한 접합부를 의존성 비순환 방향 그래프 directed acyclical graph 로 볼 수 있다<br />

면(앞에서 언급한 패키지 모델링 도구가 아주 유용하다) 엉켜져 풀기 어려울 것 같은 접합부를<br />

찾는 데 도움이 된다.<br />

이것은 뒤엉킨 모든 의존성의 출처가 대개 데이터베이스라는 것을 알게 해준다.<br />

5.5 데이터베이스<br />

다양한 서비스를 통합하는 방법으로 데이터베이스를 사용하는 데 따른 어려움에 대해 이미 충<br />

분히 논의했다. 이전에 명확히 설명한 것처럼 필자는 그러한 통합 방법을 좋아하지 않는다! 왜<br />

냐하면 우리는 데이터베이스에서 접합부를 찾아야 깔끔하게 분리할 수 있지만 데이터베이스는<br />

길들이기 매우 어려운 야수이기 때문이다.<br />

4 옮긴이_ 클로저는 2007년 리치 히키(Rich Hickey)가 고안한 자바 JVM, .NET, 자바스크립트 상에서 수행될 수 있는 리스프 언어 기<br />

반의 범용 함수형 언어다. 자세한 내용은 http://clojure.org를 참고하라.<br />

5장 모놀리스 분해하기<br />

129


5.6 문제에 대처하기<br />

첫 번째 단계는 코드 자체를 살펴보고, 데이터베이스에 읽고 쓰는 코드 부분을 보는 것이다. 일<br />

반적인 관행은 하이버네이트와 같은 프레임워크가 지원하는 저장소 계층을 두고, 객체 또는 데<br />

이터 구조를 데이터베이스와 매핑하기 쉽게 만들어서 여러분 코드를 데이터베이스와 바인딩하<br />

는 것이다. 만약 지금까지 이러한 추세를 따라왔다면 우리 코드를 경계가 있는 콘텍스트를 대표<br />

하는 패키지로 그룹화했을 것이다. 우리는 데이터베이스에 접근하는 코드도 같은 방식을 적용하<br />

고 싶어 한다. 이것은 [그림 5-1]과 같이 저장소 계층을 여러 부분으로 분리하게 만든다.<br />

그림 5-1 저장소 계층의 분리<br />

<br />

<br />

<br />

<br />

특정 콘텍스트의 코드 내에 데이터베이스 매핑 코드를 함께 배치하면 어떤 코드가 데이터베이스<br />

의 어느 부분을 사용하는지 이해할 수 있다. 예를 들어 경계가 있는 콘텍스트 단위의 매핑 파일<br />

과 같은 것을 사용한다면 하이버네이트에서는 매우 명확할 것이다.<br />

하지만 이것이 전부는 아니다. 예를 들어 재무 코드는 원장( 元 帳 ) 5 테이블 ledge table 을 사용하고,<br />

제품 목록 코드는 행 항목 테이블 line item table6 을 사용한다. 그러나 여기서 데이터베이스가 원<br />

5 옮긴이_ 자산이나 부채, 자본의 상태를 표시하는 모든 계정계좌를 설정하여 분개장에서 분개한 거래를 전부 기록하는 장부(출처: 네이버<br />

사전)<br />

6 옮긴이_ 데이터 처리를 할 때 어떤 응용 목적상 같은 레벨에 있는 일련의 데이터로서, 논리적으로 같은 줄에 인쇄될 수 있는 것. 예를 들면<br />

재고 번호, 품명, 수량, 가격 등을 가리킨다(출처: 네이버 지식백과).<br />

130 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


장 테이블로부터 행 항목 테이블까지 외부 키 관계를 생성하도록 강제하는 것이 명확하지 않다.<br />

걸림돌이 될지도 모르는 이러한 데이터베이스 수준의 제약을 보기 위해 우리는 이 데이터를 시<br />

각화하기 위한 다른 도구를 사용해야 한다. 처음에는 쉽게 구할 수 있고 테이블 관계를 그래픽<br />

으로 표현하는 것이 가능한 스키마스파이 SchemaSpy7 와 같은 도구를 사용하는 것이 좋다.<br />

이 모든 것은 궁극적으로 서비스 경계로 확장될 수 있는 테이블 간의 결합을 이해하도록 도와준<br />

다. 그러나 이러한 결합을 어떻게 끊을 것인가? 그리고 같은 테이블이 다수의 경계가 다른 콘텍<br />

스트에 사용되는 경우에는 어떻게 할 것인가? 이런 문제를 다루는 것은 쉽지 않겠지만 많은 해<br />

결책이 있으므로 가능하다.<br />

몇 가지 구체적인 예를 살펴보기 위해 온라인 뮤직 쇼핑몰을 다시 생각해보자. 우리는 경계가 있<br />

는 콘텍스트를 발견했고, 네 개의 구분되고 협업하는 서비스를 만들면서 나아가길 원한다. 이때<br />

대면하게 되는 몇 가지 구체적인 문제와 가능한 해결책을 살펴볼 것이다. 그리고 필자는 몇 가<br />

지 예를 활용해서 관계형 데이터베이스에서 접할 수 있는 문제들을 구체적으로 설명하겠지만,<br />

대안이 될 NoSQL을 사용하는 저장소에서도 유사한 문제를 겪을 수 있다.<br />

5.7 예: 외부 키 관계 깨뜨리기<br />

이 예에서 제품 목록 코드는 앨범 정보를 저장하기 위해 일반적인 행 항목 테이블을 사용하고,<br />

재무 코드는 금융 거래를 기록하기 위해 원장 테이블을 사용한다. 매월 말 조직 내 다양한 사람<br />

에게 우리가 하는 일을 보여주기 위해 보고서를 만들 필요가 있다. 우리는 멋지고 가독성이 좋은<br />

보고서를 만들고 싶어 한다. ‘SKU 8 12345 제품을 400장 판매해서 1,300달러의 수익을 냈습<br />

니다’라고 말하는 대신 ‘브루스 스프링스틴의 베스트 음반을 400장 판매해서 1,300달러의 수<br />

익을 냈습니다’처럼 유용한 정보를 더 많이 추가하고 싶어 한다. 이를 위해 재무 패키지의 보고<br />

서 코드는 SKU에 해당되는 앨범 제목을 가져오도록 행 항목 테이블에 접근할 것이다. 이때 [그<br />

림 5-2]처럼 원장 테이블에서 행 항목 테이블에 대한 외부 키 제약이 발생할 수도 있다.<br />

7 http://schemaspy.sourceforge.net<br />

8 옮긴이_ SKU(Stock Keeping Unit)는 개별 상품에 대해 재고 관리 목적으로 추적이 쉽도록 하기 위해 사용하는 식별 관리 코드를 말<br />

한다(출처: 네이버 지식백과).<br />

5장 모놀리스 분해하기<br />

131


그림 5-2 외부 키 관계<br />

<br />

<br />

<br />

<br />

<br />

그러면 이것을 어떻게 해결할 수 있을까? 두 군데 변경이 필요하다. 우선 행 항목 테이블이 제품<br />

목록 코드에 속하기 때문에 재무 코드가 이 테이블에 접근하는 것을 중단시켜야 한다. 그리고 일<br />

단 제품 목록과 재무가 독립적인 서비스로 동작하기 시작하면 우리는 데이터베이스 통합이 일어<br />

나지 않기 원할 것이다. 이 문제를 신속히 해결하기 위해 재무 코드가 행 항목 테이블에 접근하<br />

는 방법보다는 재무 코드가 호출할 수 있는 제품 목록 패키지의 API를 통해 데이터를 노출한다.<br />

이 AP는 [그림 5-3]에서 보듯이 나중에 네트워크를 통한 호출의 전신( 前 身 )이 될 것이다.<br />

그림 5-3 외부 키 관계 제거 이후<br />

<br />

<br />

<br />

<br />

<br />

<br />

이때 보고서를 생성하기 위해 두 개의 데이터베이스에 호출을 해야 하는 것은 분명하다. 이것은<br />

옳은 말이다. 그리고 두 개의 분리된 서비스의 경우에도 같은 일이 발생한다. 늘 그렇듯이 성능<br />

에 대한 우려가 제기되지만 필자에게는 이에 대해 꽤 쉬운 해답이 있다. 여러분은 얼마나 빠른<br />

132 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


시스템이 필요한가? 그리고 지금은 얼마나 빠른가? 만약 <strong>시스템의</strong> 현재 성능을 테스트할 수 있<br />

고 좋은 성능이 어느 정도인지 알 수 있다면 변경하는 데 확신이 설 것이다. 때로는 다른 뭔가를<br />

얻는 대가로 특정 기능을 좀 더 느리게 만드는 편이 옳을 수 있다(특히 저하된 성능이 아직 충분<br />

히 수용 가능하다면).<br />

하지만 외부 키 관계는 어떤가? 그 관계도 함께 사라졌다. 이것은 데이터베이스 수준이 아닌 결<br />

과적으로 얻어진 서비스가 관리해야 하는 제약 조건이다. 그리고 서비스 경계를 넘어 데이터의<br />

일관성을 보장할 구현 또는 연관된 데이터를 일괄 삭제할 수 있는 트리거 액션을 직접 구현해야<br />

함을 의미할 수 있다. 그러나 이것은 대개 기술 전문가가 결정할 사항은 아니다. 예를 들어 주문<br />

서비스에 제품 목록에 대한 ID 리스트가 있을 경우 제품 목록 중 하나가 삭제되어 주문 서비<br />

스에서 유효하지 않은 제품 ID를 참조하고 있다면 어떻게 될까? 그것을 허용해야 할까? 허용<br />

한다면 어떻게 표시해야 할까? 허용하지 않는다면 위반하지 않은 것을 어떻게 확인할 수 있을<br />

까? 이러한 질문은 사용자에 대한 <strong>시스템의</strong> 행동 방식을 정의하는 사람들을 통해 답을 구해야<br />

할 것이다.<br />

5.8 예: 공유 정적 데이터<br />

필자는 [그림 5-4]와 같이 사내 자바 프로젝트를 위해 StringUtils 클래스를 작성했을 때 많은<br />

국가 코드가 데이터베이스에 저장된 것을 본 적이 있다.<br />

그림 5-4 데이터베이스에 저장된 국가 코드<br />

<br />

<br />

<br />

5장 모놀리스 분해하기<br />

133


이것은 새로운 코드의 배포보다는 시스템이 지원하는 국가를 더 빈번히 변경할 것을 염두에 둔<br />

것처럼 보였다. 그러나 진짜 이유가 무엇이든, 이러한 데이터베이스에 저장된 공유 정적 데이터<br />

의 사례는 매우 많이 볼 수 있다. 향후에 뮤직 쇼핑몰의 모든 서비스가 이런 동일한 테이블을 참<br />

조하게 된다면 어떻게 해야 할까?<br />

몇 가지 대안이 있다. 첫째는 이 테이블을 각 패키지에 복제하는 것이다. 장기적으로 보면 그 테<br />

이블은 각 서비스 내부에서도 복제될 수 있다. 물론 이것은 잠재적으로 일관성 문제를 초래한다.<br />

예를 들어 필자가 호주 동해안에 뉴먼토피아 9 를 세워 한 테이블에만 반영하고 다른 곳에 반영<br />

하지 않는다면 어떻게 될까?<br />

둘째는 공유 정적 데이터를 코드로 다루는 것이다. 이것은 아마도 서비스의 부분으로 배포되는<br />

속성 파일에 저장되거나 열거형 개체 enumeration 가 될 수 있다. 동작 중인 데이터베이스 테이블을<br />

변경하는 것보다 설정 파일을 변경하는 것이 훨씬 용이하겠지만, 데이터 일관성에 대한 문제는<br />

여전히 존재한다. 하지만 이것은 대개 매우 합리적인 접근 방법이다.<br />

셋째는 극단적일 수 있는데, 이 정적 데이터를 특정 독립적인 서비스 안에 삽입하는 것이다. 필<br />

자가 접한 몇몇 상황에서 정적 데이터의 참조와 관련된 규모, 복잡도, 규칙들은 이 방법으로 보<br />

장하기에 충분하지만, 단지 국가 코드만을 위해 사용하기에는 아마도 과분할 것이다!<br />

대부분의 상황에서 단순한 방법이기 때문에 개인적으로 필자는 이러한 데이터를 설정 파일이나<br />

코드에 직접 삽입하는 방식을 시도하고 싶다.<br />

5.9 예: 공유 데이터<br />

좀 더 복잡한 예를 살펴보자. 변경 가능한 공유 데이터는 여러분이 시스템을 분리하려 할 때 자<br />

주 발생하는 문제가 될 수 있다. 우리의 재무 코드는 고객의 주문 결제를 추적하고, 반품할 때 환<br />

불 또한 추적한다. 한편 창고 코드는 고객 주문이 발송되고 수취되는 것을 보여주기 위해 테이<br />

블 레코드를 갱신한다. 이 모든 데이터는 웹사이트 상의 편리한 장소에 보여지고 고객은 그들의<br />

계정으로 어떤 일이 진행되는지 볼 수 있다. 이를 단순화하기 위해 [그림 5-5]와 같이 이 모든<br />

정보를 꽤 일반적인 고객 기록 테이블 내에 저장했다.<br />

9 옮긴이_ 필자의 이름 샘 뉴먼(Sam Newman)을 딴 가상의 국가<br />

134 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


CHAPTER 8<br />

모니터링<br />

필자가 지금까지 보여주고자 한 것처럼 시스템을 더 세분화된 <strong>마이크로서비스</strong>로 분해하면 많은<br />

혜택을 얻지만 실환경 시스템을 모니터링하는 관점에서 볼 때 복잡성도 증가한다. 이 장에서는<br />

세분화된 시스템에서 발생하는 문제의 인식과 모니터링에 연관된 도전을 살펴보고 이 둘을 모<br />

두 취하기 위해 여러분이 할 수 있는 것에 대해 설명할 것이다.<br />

어느 불타는 금요일 오후의 사무실 장면을 떠올려보자. 팀은 업무를 마치고 주말을 시작하기 위<br />

해 살며시 술집으로 빠져나가기를 고대하고 있다. 이때 갑자기 이메일을 받게 된다. ‘웹사이트가<br />

오동작하고 있어!’ 트위터는 회사의 장애 내용으로 도배되고 보스는 잔소리를 해대며 불타는 주<br />

말의 기대는 연기처럼 사라진다.<br />

여러분이 가장 먼저 알아야 할 것은 무엇일까? 도대체 어디서 잘못된 것일까?<br />

모놀리식 애플리케이션의 세계에서는 적어도 분석을 시작할 아주 명확한 지점이 있다. 웹사이트<br />

가 느려졌어? 한 곳만 보면 돼. 웹사이트에서 이상한 에러가 발생하고 있어? 한 곳만 보면 돼.<br />

CPU 사용량이 100%야? 역시 한 곳만 보면 돼. 뭔가 타는 냄새가 나? 어떤 것이든 여러분은<br />

다 알고 있다. 단일 장애 지점 single point of failure 이 있다는 것은 장애 분석을 다소 쉽게 만든다!<br />

그럼 이제 <strong>마이크로서비스</strong> 기반의 시스템을 생각해보자. 우리가 사용자에게 제공하는 기능은 다<br />

양한 작은 서비스들에 의해 제공된다. 그중 일부 서비스는 그들의 임무를 완수하기 위해 훨씬 더<br />

많은 서비스와 통신한다. 이러한 방식은 많은 혜택이 있지만 모니터링의 세계에서는 우리가 다<br />

뤄야 할 더 복잡한 문제가 존재한다. 참고로 그 혜택은 정말로 좋은 것이다. 그렇지 않다면 이 책<br />

을 읽는 것은 시간 낭비다.<br />

217


지금 우리에겐 모니터링해야 할 많은 서버와 꼼꼼히 살펴봐야 할 수많은 로그파일, 네트워크 지<br />

연으로 발생할 수 있는 많은 문제가 있다. 그렇다면 이 문제에 어떻게 접근해야 할까? 처리하지<br />

않으면 혼란스럽고 엉망진창이 되는 사안에 대해 이해할 필요가 있다. 이런 난감한 상황은 누구<br />

라도 금요일 오후(또는 언제라도 발생할 때)에는 피하고 싶기 마련이다.<br />

해결책은 매우 단순하다. 즉, 작은 것들을 모니터링하고 전체 상황을 볼 수 있도록 취합하라. 이<br />

를 위해 가장 단순한 시스템인 단일 노드에서부터 시작할 것이다.<br />

8.1 단일 서비스, 단일 서버<br />

[그림 8-1]은 매우 단순한 구성(단일 호스트에서 실행되는 단일 서비스)을 보여준다. 우리는 무<br />

언가 잘못되어 가고 있다는 것을 알기 위해 모니터링이 필요하며 이를 통해 해결할 수 있다. 그<br />

렇다면 무엇을 관찰해야 할까?<br />

그림 8-1 단일 호스트 상의 단일 서비스<br />

<br />

<br />

우선 우리는 호스트 자체를 모니터링하고 싶어 한다. CPU와 메모리는 매우 유용한 정보다. 시<br />

스템이 정상일 때 이들의 정상 범위를 알고 있어야 범위를 벗어날 때 주의 경보 alert 를 보낼 수 있<br />

다. 자체 모니터링 소프트웨어를 사용하고자 한다면 나기오스와 같은 것을 사용할 수 있고 뉴 렐<br />

릭 New Relic1 과 같은 호스팅 서비스를 이용할 수 있다.<br />

그다음으로 서버 자체의 로그에 접근하고 싶어 한다. 만약 사용자가 에러를 리포트한다면 로그<br />

는 에러를 추출해야 하고 바라건대 언제 어디서 그것이 발생하는지도 알려주어야 한다. 이때 단<br />

1 옮긴이_ 류 씨네(Lew Cirne)가 설립한 웹과 모바일 애플리케이션을 실시간 모니터링하는 소프트웨어다. SaaS 모델을 기반으로 클라<br />

우드, 온-프레미스(on-premise) 또는 하이브리드 형태로 실행될 수 있다. 제품명 뉴 렐릭은 설립자 류 씨네의 영문 철자를 조합하여 만<br />

든 것이다. 자세한 내용은 http://newrelic.com을 참고하기 바란다.<br />

218 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


일 호스트 상에서는 단지 로그인 후 로그를 스캔하기 위해 명령행 도구를 사용하여 그 정보를<br />

얻을 수도 있다. 게다가 오래된 로그가 디스크 공간을 다 채우지 않도록 logrotate 2 를 사용할<br />

수 있다.<br />

끝으로 애플리케이션 자체를 모니터링하고 싶어 한다. 최소한 서비스의 응답시간을 모니터링하<br />

는 것이 좋다. 여러분은 아마도 서비스 앞단에 위치한 웹 서버의 로그나 서비스 자체의 로그를<br />

관찰하면서 응답시간을 모니터링할 수 있을 것이다. 훨씬 더 발전한다면 리포팅하고 있는 에러<br />

의 개수를 추적하고 싶어 할 수도 있다.<br />

시간이 지나 부하가 증가하면 우리는 확장할 필요를 느낀다...<br />

8.2 단일 서비스, 다수 서버<br />

[그림 8-2]에서 볼 수 있듯이 실행되는 서비스의 복제본들이 분리된 호스트 상에 있다면 요청은<br />

부하 <strong>분산</strong>기 load balancer 를 통해 다른 서비스 인스턴스로 전달된다. 우리는 여전히 이전처럼 동일<br />

한 모든 것을 모니터링하고 싶어 하지만 문제를 격리할 수 있는 방법으로 진행해야 한다.<br />

그림 8-2 다수의 호스트에 <strong>분산</strong>된 단일 서비스<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

이 시점에 우리는 여전히 호스트 레벨의 측정지표 metrics 를 추적하고 지표에 대한 주의 경보를 원<br />

하지만 이제 개별 호스트뿐만 아니라 모든 호스트에 발생된 것인지도 알기 원한다. 다시 말해,<br />

2 옮긴이_ 리눅스에서 로그 로테이션을 하는 일반적인 방법 중 하나다. 일, 주, 월 단위 및 로테이션 횟수를 지정할 수 있다.<br />

8장 모니터링<br />

219


모든 것을 취합하고 세부 분석을 할 수 있어야 한다. 나기오스를 통해 호스트 그룹으로 나눌 수<br />

있어 지금까지는 괜찮다. 아마도 유사한 방식을 애플리케이션에 적용하기에 충분할 것이다.<br />

그다음은 로그다. 다수의 서버에서 실행되는 서비스가 있다면 로그를 보기 위해 각 박스(서버)<br />

에 로그인하는 것은 싫증나는 일이다. 하지만 단지 몇 개의 호스트만 있다면 여러 호스트에 동일<br />

한 명령 실행이 가능한 SSH 멀티플랙서 ssh-multiplexer 와 같은 도구를 사용할 수 있다. 큰 모니터<br />

에서 grep "Error" app.log를 실행하여 문제 원인을 찾을 수 있다.<br />

응답시간 추적과 같은 작업은 부하 <strong>분산</strong>기에서 추적해서 쉽게 취합할 수 있다. 하지만 부하 <strong>분산</strong><br />

기의 오동작도 문제가 될 수 있으므로 <strong>분산</strong>기도 추적 대상이 되어야 한다. 이때 부하 <strong>분산</strong>기가<br />

애플리케이션에서 비정상적인 노드를 발견하면 제거하도록 설정할 것이기 때문에 우리는 정상<br />

적인 서비스가 어떻게 동작하는지에 더 많은 관심을 가질 것이다. 이 장에서 이러한 문제에 대한<br />

몇 가지 아이디어를 얻기 기대한다.<br />

8.3 다수 서비스, 다수 서버<br />

[그림 8-3]에서는 모든 것이 더 흥미롭다. 다수의 물리적 또는 가상 호스트에서 실행되는 다수<br />

의 서비스는 사용자에게 기능을 제공하기 위해 협업하고 있다.<br />

그림 8-3 다수의 호스트에 <strong>분산</strong>되어 협업하는 다수의 서비스<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

220 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


많은 호스트에서 생성되는 수천 줄의 로그에서 여러분이 찾으려는 에러를 어떻게 발견할 수 있<br />

을까? 한 서버가 오동작하는 것인지 또는 시스템 전체적인 문제인지 어떻게 판별할 수 있을까?<br />

그리고 여러분은 많은 호스트 사이에서 발생한 호출 체인의 심층부에서 발견된 에러를 다시 추<br />

적하고 그 원인을 찾아낼 수 있을까?<br />

해결책은 로그부터 애플리케이션 측정지표까지 가능한 한 많은 수집 collection 과 집중식 취합 central<br />

aggregation 을 하는 것이다.<br />

8.4 로그, 로그, 더 많은 로그...<br />

이제 실행하는 호스트의 수가 우리에게 난관이 된다. 더 이상 로그를 추출하기 위한 SSH 멀티<br />

플랙싱으로는 어림도 없으며 모든 호스트의 터미널을 보여주기에 충분히 큰 스크린도 없다. 대<br />

신 우리는 로그를 수집하고 중앙에서 접근하기 위해 전문적인 서브시스템을 사용하려 한다. 이<br />

에 대한 한 가지 예는 많은 로그 파일 포맷을 파싱하고 추가 분석을 위해 하부 시스템에 전송할<br />

수 있는 로그스태쉬 logstash3 다.<br />

키바나 Kibana4 는 [그림 8-4]처럼 로그를 보기 위한 일레스틱서치 기반 시스템 ElasticSearch-backed<br />

system 이다.<br />

그림 8-4 집계된 로그를 보기 위해 키바나 사용하기<br />

<br />

<br />

<br />

<br />

<br />

<br />

3 http://logstash.net/<br />

4 http://bit.ly/1BrIp6a<br />

8장 모니터링<br />

221


우리는 로그 검색을 위한 질의 구문 query syntax 과 특정 날짜와 시간 범위 또는 일치하는 문자열을<br />

찾기 위한 정규 표현식도 사용할 수 있다. 또한 키바나는 전송된 로그에서 그래프도 생성할 수<br />

있는데, 예를 들어 시간에 따라 얼마나 많은 에러가 발생했는지 한번에 보는 것이 가능하다.<br />

8.5 다수 서비스 간의 측정지표 추적<br />

다른 호스트의 로그를 살펴보는 것은 어렵기 때문에 우리는 측정지표를 수집하고 보기 위한 더<br />

나은 방법을 검토해야 한다. 복잡한 시스템에서 측정지표를 살펴볼 때는 어느 것이 정상 상태인<br />

지 알기 어렵다. 웹사이트에서 초당 거의 50개의 4XX HTTP 에러 코드를 보여준다면 이것은<br />

나쁜 것인가? 제품 목록 서비스에 대한 CPU 부하가 점심시간 이후에 20% 증가되었다면 무언<br />

가 잘못된 것일까? 언제 바짝 긴장하고 안도할지 아는 비결은 명확한 패턴이 드러나도록 오랜<br />

기간에 걸쳐 <strong>시스템의</strong> 행동 방식에 대한 측정지표를 수집하는 것이다.<br />

복잡한 환경에서는 서비스들의 인스턴스가 매우 빈번히 프로비저닝되기 때문에 우리가 선택한<br />

시스템이 새로운 호스트로부터 측정지표를 매우 쉽게 수집하기 원한다. 예를 들어 우리는 평균<br />

CPU 부하와 같이 전체 시스템에 대해 집계된 특정 측정지표를 볼 수 있기를 기대하지만 특정<br />

서비스에 대한 모든 인스턴스나 개별 인스턴스에 대한 측정지표까지도 집계하기 원할 것이다.<br />

이것은 이러한 구조를 추론할 수 있도록 메타데이터와 측정지표를 연결할 수 있어야 한다는 것<br />

을 의미한다.<br />

그래파이트 Graphite 는 이를 매우 쉽게 만들어주는 시스템 중 하나다. 아주 단순한 API를 제공해<br />

서 실시간으로 측정지표를 전송할 수 있고 현재 상황을 보여주는 차트나 다른 형태의 디스플레<br />

이를 생성하기 위해 그 측정지표에 대한 질의도 할 수 있다. 볼륨을 처리하는 방식 역시 흥미로<br />

운데, 볼륨이 지나치게 커지지 않도록 오래된 측정지표의 해상도를 낮춰 효과적인 구성이 가능<br />

하다. 예를 들어 호스트의 CPU 정보를 최근 10분 동안은 10초 단위로 기록하고, 최근 하루 동<br />

안은 1분 단위로, 최근 수년 동안은 30분 단위로 집계할 수 있다. 이 방식을 통해 거대한 저장<br />

소 없이 장기간의 시스템 행동 정보를 저장할 수 있다.<br />

그래파이트는 여러 표본을 취합하고 한 표본을 따라 자세히 검색함으로써 전체 시스템, 서비<br />

스 그룹 또는 단일 인스턴스에 대한 응답시간을 알 수 있다. 만약 어떤 연유로 그래파이트가 여<br />

러분에게 적합하지 않다면 선택하려는 다른 도구에서 이와 유사한 기능이 있는지 확인하라. 그<br />

222 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


리고 필요할 경우 자체 리포팅과 대시보드를 제공하기 위해 원본 데이터에 접근할 수 있는지도<br />

확인하라.<br />

측정지표의 추이를 이해하는 또 다른 혜택은 용량 계획 capacity planning 이다. 지금 한계에 도달하<br />

고 있을까? 더 많은 호스트가 필요할 때까지 얼마나 걸릴까? 과거에 물리적인 호스트를 도입하<br />

는 것은 대개 연간 업무였다. 하지만 IaaS infrastructure as a service 업체에 의해 주문형 컴퓨팅이 제<br />

공되는 새로운 시대인 지금 우리는 확장이나 축소는 수초는 아니더라도 수분 만에 가능하다. 이<br />

는 우리의 사용 패턴을 이해하면 필요에 부응하는 충분한 인프라스트럭처를 보유할 수 있음을<br />

의미한다. 트렌드의 추적과 트렌드에 따른 할 일에 대해 더 잘 알게 될수록 <strong>시스템의</strong> 비용 효율<br />

성과 응답성도 높아진다.<br />

8.6 서비스 측정지표<br />

여러분이 리눅스 머신에 콜렉트디를 설치하고 그래파이트로 연결한다면 실행 중인 운영 체제에<br />

서 수많은 측정지표가 생성된다는 것을 알게 된다. 같은 방식으로 엔진엑스나 바니쉬처럼 서브<br />

시스템도 응답시간 또는 캐시 적중률과 같은 유용한 정보를 제공하고 있다. 그렇다면 여러분의<br />

서비스는 어떤가?<br />

필자는 서비스 스스로 기본적인 측정지표를 발산해야 한다고 강력히 제안한다. 웹 서비스라면<br />

최소한 기본으로 응답시간과 에러율 같은 측정지표를 노출해야 한다. 만약 이러한 일을 대신하<br />

는 웹 서버가 여러분 서버 앞단에 없다면 그것은 필수다. 그러나 여러분은 더 나아가야 한다. 예<br />

를 들어 계정 서비스 account service 는 고객이 과거 주문 내역을 본 횟수를 보여주거나 웹 쇼핑몰이<br />

지난 하루 동안 얼마나 많은 돈을 벌었는지 기록하기 원할 수 있다.<br />

왜 이러한 것에 관심을 가지는 걸까? 여러 가지 이유가 있다. 첫째, 소프트웨어 기능의 80%는<br />

결코 사용되지 않는다는 오래된 속설이 있다. 지금은 그 수치가 얼마나 정확한지 언급할 수 없지<br />

만, 거의 20년간 소프트웨어를 개발해온 사람으로서 실제로 사용되지 않는 기능에 엄청난 시간<br />

을 보낸 것을 잘 알고 있다. 사용되는 기능인지 아는 것이 좋지 않을까?<br />

둘째, 우리는 시스템을 어떻게 개선해야 할지 알기 위해 사용자가 우리 시스템을 사용하는 방식<br />

에 이전보다 더 잘 대응하고 있다. 시스템이 어떻게 동작하는지 알려주는 측정지표만 여기에 도<br />

움을 줄 수 있다. 새 버전의 웹사이트를 출시하고 음반 목록 서비스 catalog service 의 장르별 검색수<br />

8장 모니터링<br />

223


가 크게 오른 것을 발견한다면 이것은 문제일까? 아니면 예상한 일일까?<br />

셋째, 우리는 어떤 데이터가 유용할지 결코 알 수 없다! 필자는 어떤 것을 이해하는 데 도움을 주<br />

는 데이터를 수집할 기회가 한참 지난 후에야 그 데이터를 원한 적이 한두 번이 아니다. 그래서<br />

나중에 처리하기 위해 측정지표 시스템에 모두 노출하고 의존하는 실수를 하곤 한다.<br />

서비스가 측정지표를 표준 시스템에 전송하는 것을 도와주는 라이브러리들이 다양한 플랫폼<br />

에서 동작한다. 코다헤일 Codahale5 의 측정지표 라이브러리 6 는 JVM용 라이브러리의 한 예로 측<br />

정지표를 카운터, 타이머 또는 측정기로 저장하게 해준다. 예를 들어 시간 설정 측정지표 timeboxing<br />

metrics<br />

기능을 제공해서 최근 5분 동안의 주문수와 같은 측정지표를 지정할 수 있다. 그리<br />

고 그래파이트와 다른 집계 및 리포팅 시스템에 대한 데이터 전송 기능을 기본적으로 지원하고<br />

있다.<br />

8.7 합성 모니터링 7<br />

예를 들어 우리는 정상 CPU 수준을 정하거나 허용 가능한 응답시간을 정해서 서비스가 정상인<br />

지 가늠할 수 있다. 측정지표의 현재 수치가 안전수준을 초과하는 것이 모니터링 시스템에 감지<br />

된다면 다방면으로 유용한 나기오스와 같은 도구를 통해 주의 경보를 보낼 수 있다.<br />

그렇지만 여러모로 이 수치들은 우리가 실제로 추적하려는 것인 시스템이 작동하고 있는가와 가<br />

까이 있다. 하지만 서비스 간의 상호작용이 복잡할수록 실제로 그 질문의 대답에도 점점 더 거리<br />

가 멀어진다. 그렇다면 모니터링 시스템을 마치 사용자처럼 동작하게 만들어 무언가 잘못될 때<br />

보고하도록 프로그램하면 어떨까?<br />

필자는 2005년 당시 투자 은행용 시스템을 <strong>구축</strong>하는 소트워크스의 작은 팀에서 일할 때 이것<br />

5 옮긴이_ 코다헤일은 모니터링 <strong>분산</strong> 시스템 등에 대한 저명한 오픈 소스 소프트웨어 개발자이자 블로거다. 애플리케이션 레벨 모니터링에<br />

관심이 있다면 그의 측정지표 라이브러리와 CodeConf 2011에서 발표한 「Metrics, Metrics, Everywhere」 발표 영상 및 자료를 보<br />

기 바란다. 요즘은 소식이 뜸한 그의 블로그 http://codahale.com에서도 좋은 글을 만날 수 있다.<br />

6 http://metrics.codahale.com<br />

7 옮긴이_ 웹 애플리케이션을 모니터링하는 방법에 따라 합성 모니터링과 실사용자 모니터링으로 나눌 수 있다. 합성 모니터링은 통<br />

제된 모니터링(directed monitoring), 능동 모니터링(active monitoring) 또는 유의적 모니터링(semantic monitoring)으<br />

로 불리며 운영 중인 시스템에 자동화된 테스트의 하위 집합을 실행해 모니터링하는 기술이다. https://martinfowler.com/bliki/<br />

SyntheticMonitoring.html을 참고하라.<br />

224 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


을 처음으로 진행했다. 거래일 내내 시장의 변화를 대표하는 수많은 이벤트가 밀려왔다. 우리 업<br />

무는 이러한 변화에 대응하고 은행의 포트폴리오에 영향을 주는지 살피는 것이었다. 이벤트 도<br />

착 후 10초 이내에 모든 계산을 마치는 것을 목표로, 꽤 빡빡한 마감시간 하에서 일하고 있었다.<br />

시스템 자체는 분리된 5개의 서비스로 구성되었고 적어도 그중 한 서비스는 한 컴퓨팅 그리드에<br />

서 실행되고 다른 것들은 은행의 재해복구센터에 있는 250대의 데스크톱 호스트의 사용되지<br />

않는 CPU 주기를 찾아서 사용하고 있었다.<br />

시스템 내의 변경 부분의 수는 우리가 수집한 저수준의 많은 측정지표로부터 수많은 노이즈가<br />

발생한다는 것을 의미했다. 우리는 CPU 수치 또는 일부 개별 컴포넌트의 지연시간처럼 측정지<br />

표를 통한 <strong>시스템의</strong> 정상 good 상태를 이해하기 위해 점진적인 시스템 확장이나 수개월간의 운영<br />

혜택을 누릴 수 없었다. 우리가 택한 방법은 하부 시스템에는 기록되어 있지 않은 일부 포트폴<br />

리오의 가격을 정하기 위해 가짜 이벤트를 생성하는 것이었다. 거의 매분마다 나기오스가 가짜<br />

이벤트를 적절한 큐에 삽입하는 명령행 작업을 수행하도록 했다. 테스팅에만 사용되는 임시 기<br />

록판 junk book 에 그 결과가 표시되는 점을 제외하고, 시스템은 여느 다른 작업처럼 그 이벤트 하<br />

나를 골라 다양한 연산을 수행했다. 만약 특정 시간 내에 재산정된 가격이 나타나지 않는다면 나<br />

기오스는 이것을 문제로 보고 리포트한다.<br />

생성된 가짜 이벤트는 합성(가상) 트랜잭션 synthetic transaction 의 한 예다. 우리는 시스템이 유의미<br />

하게 semantically 동작하고 있음을 보장하기 위해 이 합성된 트랜잭션을 사용했고, 이 <strong>기법</strong>이 종종<br />

유의적 모니터링 semantic monitoring 이라고 불리는 이유다.<br />

실전에서는 저수준 측정지표에 대한 경고보다 위와 같이 유의적 모니터링을 수행하기 위한 합성<br />

트랜잭션 사용이 시스템 상의 문제를 훨씬 더 잘 나타내는 지표 indicator 라는 사실을 발견했다. 하<br />

지만 유의적 모니터링으로 문제를 리포트할 때는 상세한 이유가 필요하므로 합성 트랜잭션이 저<br />

수준의 측정지표를 대체하는 것은 아니다.<br />

8.7.1 유의적 모니터링 구현하기<br />

과거에 유의적 모니터링을 구현하는 것은 꽤 도전하기 벅찬 일이었지만 세상이 바뀌어 이제는<br />

구현하는 게 아주 쉬워졌다! 여러분 시스템에 테스트를 수행하고 있는가? 그렇지 않다면 7장을<br />

읽고 오라. 모두 준비되었나? 그럼 시작하자!<br />

특정 서비스나 시스템 전체의 엔드 투 엔드 테스트를 살펴보면 유의적 모니터링 구현에 필요한<br />

8장 모니터링<br />

225


많은 것을 이미 보유하고 있다는 것을 알 수 있다. 즉, 시스템은 테스트 실행과 결과 확인에 필요<br />

한 수단을 이미 제공하고 있다. 그러므로 이 테스트의 일부 집합을 시스템을 지속적으로 모니터<br />

링하는 방법으로 사용하는 것은 어떨까?<br />

물론 추가 작업이 몇 가지 있다. 먼저 테스트의 데이터 요구 사항에 대해 주의해야 한다. 실제 데<br />

이터가 시간이 지나며 바뀐다면 이 테스트를 다양한 데이터에 적용할 방법을 찾거나 다른 데이<br />

터 소스를 사용할 수 있다. 예를 들어 실환경에서 정해진 데이터의 집합을 사용하는 가짜 사용자<br />

집합을 만들 수 있다.<br />

또한 예측하지 못한 부작용을 우발적으로 만들지 않도록 보장해야 한다. 한 예로 필자의 친구는<br />

실환경 주문 시스템에서 테스트를 수행한 전자상거래 회사의 실수에 대해 이야기를 해주었다.<br />

결국 엄청나게 많은 세탁기가 그 회사의 본사에 배달될 때까지 누구도 그 실수를 까맣게 모르고<br />

있었다고 한다.<br />

8.8 상관관계 ID<br />

최종 사용자에게 어떠한 기능이라도 제공하기 위해서는 수많은 서비스 상호작용이 필요하므로<br />

하나의 초기 호출로 시작하여 다수의 하위 서비스에 대한 호출로 분화할 수 있다. 예를 들어 고<br />

객 가입의 사례를 생각해보자. 고객은 양식에 맞게 모든 인적 세부 사항을 입력하고 제출 버튼을<br />

클릭한다. 그 뒷단에서 결제 서비스 payment service 를 통해 신용 카드 세부 사항의 유효성을 확인<br />

하고, 우편 서비스 postal service 에 가입 환영 패키지를 우편으로 보내도록 전달하고, 이메일 서비<br />

스 email service 를 이용하여 가입 환영 이메일을 보낸다. 이때 결제 서비스 호출에서 이상한 에러가<br />

발생하면 어떻게 될까? 우리는 11장에서 장애 처리에 대해 깊이 논의하겠지만 문제 분석의 어<br />

려움을 고려해야 한다.<br />

로그를 보았더니 에러를 등록한 서비스가 결제 서비스였다. 운이 좋다면 어떤 요청이 문제를 야<br />

기했는지 알아낼 수 있고 심지어 호출 인자도 볼 수 있을 것이다. 이것을 단순한 예라고 생각하<br />

고 하나의 초기 요청이 하위 호출 체인과 비동기 방식으로 처리되도록 전송될 이벤트도 생성할<br />

수 있다. 문제를 재현하고 고치기 위해 호출 흐름을 어떻게 재구성할 수 있을까? 우리가 필요한<br />

것은 초기 호출을 더 넓은 맥락에서 아는 것이다. 다시 말해, 스택 트레이스 stack trace 로 한 것처럼<br />

상향 호출 체인을 추적할 수 있다.<br />

226 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


여기서 유용한 방법 중 하나는 상관관계 ID correlation ID 를 이용하는 것이다. 첫 호출이 이뤄질 때<br />

호출에 대한 전역 호출 식별자 globally unique identifier (GUID)를 생성하고 [그림 8-5]처럼 후속하<br />

는 모든 호출에 전달한다. 그리고 로그 레벨이나 날짜와 같은 구성 요소와 함께 구조화된 방식<br />

으로 로그에 넣을 수 있다. 이제 올바른 로그 집계 도구를 통해 시스템에서 일관되게 추적할 수<br />

있을 것이다.<br />

15-02-2014 16:01:01 Web-Frontend INFO [abc-123] Register<br />

15-02-2014 16:01:02 RegisterService INFO [abc-123] RegisterCustomer ...<br />

15-02-2014 16:01:03 PostalSystem INFO [abc-123] SendWelcomePack ...<br />

15-02-2014 16:01:03 EmailSystem INFO [abc-123] SendWelcomeEmail ...<br />

15-02-2014 16:01:03 PaymentGateway ERROR [abc-123] ValidatePayment ...<br />

그림 8-5 다수 서비스 간의 호출 체인을 추적하기 위해 상관관계 ID 사용하기<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

물론 여러분은 각각의 서비스가 상관관계 ID의 전달을 이해하도록 해야 한다. 그러기 위해서<br />

는 표준화가 필요하고 시스템 경계를 넘어 더 강력히 시행되어야 한다. 하지만 한번 완료하고<br />

나면 모든 종류의 상호작용을 추적하기 위한 도구도 만들 수 있다. 이렇게 만들어진 도구는 호출<br />

의 전체 연결 단계를 파악할 수 있으므로 이벤트 폭풍 event storm8 과 코너 케이스 corner case9 를 추적<br />

8 옮긴이_ 짧은 기간 동안 시스템에 유입되는 다양하고 수많은 이벤트를 의미<br />

9 옮긴이_ 공학에서 코너 케이스는 정상 범위의 매개 변수와 복합적인 외부 조건의 상호작용으로 발생되는 특수한 문제 또는 상황이다. 매<br />

개 변수의 극한 범위와 연관된 엣지 케이스(edge case) 또는 경계 케이스(boundary case)도 참고하기 바란다.<br />

8장 모니터링<br />

227


하거나 심지어 비정상적인 고비용 트랜잭션을 확인하는 데 이용할 수 있다.<br />

집킨 Zipkin10 과 같은 소프트웨어는 많은 시스템 경계를 넘나드는 호출도 추적할 수 있다. 구글 자<br />

체의 추적 시스템인 댑퍼 Dapper11 의 아이디어에 기반을 둔 집킨은 데이터 표현을 도와주는 UI<br />

와 함께 서비스 상호 호출을 매우 자세히 추적하는 기능을 제공한다. 필자는 개인적으로 맞춤<br />

화된 클라이언트와 수집 시스템을 지원하는 집킨의 요구 사항이 다소 무겁다고 생각한다. 여러<br />

분이 이미 다른 목적으로 로그 취합을 원한다는 것을 고려한다면 이미 수집 중인 데이터를 사<br />

용하는 것이 다른 데이터 소스에 연결하는 것보다 훨씬 쉽다고 느낄 것이다. 즉, 이와 같은 서비<br />

스 상호 간의 호출을 추적하기 위해 보다 진보된 도구가 필요할 수 있다.<br />

상관관계 ID와 연관된 실질적인 문제 중 하나는 처음부터 그 ID가 있어야만 분석할 수 있는 문<br />

제를 접하기 전까지 상관관계 ID의 필요성을 모른다는 것이다! 나중에 상관관계 ID를 변조해<br />

서 끼워 넣는 것은 매우 어렵기 때문에 이는 특히 더 문제가 된다. 따라서 호출 체인을 쉽게 재구<br />

성하기 위해서는 표준화된 방법으로 처리해야 한다. 비록 이 일이 여러분에게 부가적인 사전 작<br />

업처럼 보이더라도 가능한 한 빨리 도입하기를 강력히 제안한다. 이벤트 기반의 <strong>아키텍처</strong> 패턴<br />

을 사용하고 있다면 특이한 뜻밖의 행동이 발생할 수 있기 때문이다.<br />

일관된 상관관계 ID 전달은 공유 씬 클라이언트 랩퍼 라이브러리 thin client wrapper library 를 사용하<br />

는 중요한 근거가 된다. 특정 규모로 커지면 모두가 하위 서비스를 올바른 방식으로 호출하고 올<br />

바른 종류의 데이터 수집을 보장하기 어려워진다. 호출 체인에서 한 서비스라도 이 ID를 누락<br />

한다면 중요한 정보를 잃게 된다. 여러분이 처음부터 상관관계 ID를 지원하는 자체 클라이언<br />

트 라이브러리를 만들기로 결정한다면 그 라이브러리를 매우 가볍게 thin 유지하고 특정 생산자<br />

서비스 12 와 결합되지 않도록 하라. 예를 들어 통신을 위한 하부 프로토콜로 HTTP를 사용하<br />

고 있다면 HTTP 헤더 안에 상관관계 ID를 전파하도록 코드에 추가하는 방식으로 표준 HTTP<br />

클라이언트 라이브러리를 감싸라.<br />

10 https://twitter.github.io/zipkin/<br />

11 옮긴이_ http://research.google.com/pubs/pub36356.html<br />

12 옮긴이_ 서비스를 제공하는 생산자 서비스를 의미하며, 라이브러리가 특정 생산자 서비스에 종속되지 않도록 <strong>설계</strong>하라는 의미다.<br />

228 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


CHAPTER 11<br />

대규모 <strong>마이크로서비스</strong><br />

작고 멋진 사례만 다룬다면 만사가 쉬워 보일 것이다. 그러나 실제 세상은 그보다 복잡한 게 사<br />

실이다. 우리 <strong>마이크로서비스</strong>가 단순하고 초라한 <strong>아키텍처</strong>에서 시작해서 더욱 복잡하게 발전<br />

한다면 어떨까? 여러분이 분리된 많은 서비스의 장애를 처리하거나 수백 개의 서비스를 관리해<br />

야 한다면? 그리고 사람 수보다 더 많은 <strong>마이크로서비스</strong>가 있을 때의 대응 패턴은 무엇일까? 이<br />

장에서는 이러한 것들에 대해 알아보도록 하자.<br />

11.1 장애는 어디에서나 발생한다<br />

우리는 상황이 안 좋아질 수 있다는 것을 잘 알고 있다. 즉, 하드 디스크는 고장나고 소프트웨어<br />

는 오류가 발생한다. 그리고 <strong>분산</strong> 컴퓨팅의 오류 1 를 읽어본 사람은 네트워크는 신뢰할 수 없다<br />

는 것을 알게 된다. 우리는 장애의 원인을 제한하기 위해 최선을 다하지만 특정 규모에서의 장<br />

애는 피할 수 없다. 예를 들어 하드 디스크는 전보다 더 안정적이지만 결국에는 고장날 것이다.<br />

더 많은 하드 디스크가 있다면 개별 장치에 대한 장애 가능성도 높아진다. 즉, 장애는 대규모 환<br />

경에서 통계적으로 필연적이다.<br />

아주 극단적인 규모를 고려하지 않더라도 실패의 가능성을 수용하는 편이 더 낫다. 예를 들어<br />

1 옮긴이_ 1994년 피터 도이취(L Peter Deutsch)와 선 마이크로시스템즈의 동료들은 <strong>분산</strong> 컴퓨팅에서 아키텍트나 <strong>설계</strong>자가 범하기 쉬<br />

운 7가지 가정을 소개했고, 그 후 자바의 창시자인 제임스 고슬링(James Gosling)이 다른 오류를 추가해서 <strong>분산</strong> 컴퓨팅의 8가지 오류<br />

로 알려졌다. http://bit.ly/1En0t51을 참고하라.<br />

275


우리가 한 서비스의 장애를 훌륭히 처리할 수 있다면 예상치 못한 중단 outage 보다 계획된 중단이<br />

훨씬 처리하기 쉽기 때문에 서비스의 현장 업그레이드 in-place upgrade2 도 수행할 수 있다.<br />

우리는 불가피한 것을 막는 데 좀 더 적은 시간을, 그리고 그것을 세련되게 처리하는 데 더 많은<br />

시간을 할애할 수도 있다. 장애를 막기 위해 아주 많은 조직이 프로세스를 만들고 통제를 하지<br />

만 처음 발생한 장애를 실제로 더 쉽게 복구할 생각은 하지 않는 것에 필자는 놀랐다.<br />

어떤 것이든 고장날 수 있다는 가정을 명심하는 것은 문제의 해결 방법을 다르게 생각하도록 만<br />

든다.<br />

필자가 수년 전 구글 캠퍼스에 있을 때 이러한 사례를 보았다. 마운틴 뷰 Mountain View 에 위치한<br />

구글 빌딩의 안내실 구역에 전시용으로 구형 머신의 랙 장비들이 비치되어 있었는데 필자는 몇<br />

가지를 주목했다. 먼저 주목한 것은 이 서버들은 서버 케이스가 없었고 랙 슬롯에 베어 마더보드<br />

만 장착되어 있었다. 하지만 필자가 가장 주목한 점은 하드 드라이브가 벨크로 velcro 로 고정되어<br />

있었다는 것이었다. 구글 직원에게 왜 그런지 물어보니 그의 대답은 이러했다. “아, 하드 드라<br />

이브 고장이 너무 잦아서 고장난 하드 드라이브를 꺼내버리고 새 것으로 교체할 때는 나사로 고<br />

정시키지 않고 벨크로로 고정시켜요.”<br />

다시 말하지만 대규모 상황에서는 최고가의 하드웨어로 구성된 가장 좋은 구성품 세트를 구입<br />

하더라도 부품의 고장을 피할 수 없다. 따라서 여러분은 어떤 장애든 결국 발생한다는 것을 가정<br />

해야 한다. 이러한 생각을 염두에 두고 장애에 대한 계획을 세운다면 다양한 절충안을 준비할 수<br />

있다. 서버는 고장날 수 있고 고장날 것이라는 사실을 잘 다루는 시스템이라는 것을 알고 있으면<br />

서 왜 그렇게 고장에 대해 많은 비용을 들여야 할까? 단일 노드의 회복성을 너무 걱정하지 말고<br />

구글에서 한 것처럼 벨크로와 저렴한 구성품으로 된 베어 마더보드를 사용하는 것은 어떨까?<br />

11.2 얼마나 많아야 너무 많은 건가?<br />

우리는 7장에서 교차기능 요구 사항에 대해 다뤘다. 교차기능 요구 사항의 이해는 데이터의 내<br />

구성, 서비스의 가용성, 처리량, 서비스의 허용 지연시간 같은 측면을 모두 고려하는 것이다. 이<br />

2 옮긴이_ 업그레이드 전략은 해당 시스템에 전체 업그레이드를 수행하는 일괄 업그레이드와 신규 시스템에 차례로 업그레이드를 수행하는<br />

병행 업그레이드(side-by-side upgrade)로 구분된다.<br />

276 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


러한 기술 중 다수가 이 장에서 다뤄졌고 이러한 요구 사항의 구현 방안들을 다른 장에서 논의했<br />

다. 하지만 오직 여러분만이 그 요구 사항이 어떤 것인지 정확히 알고 있다.<br />

증가하는 부하나 개별 노드의 고장에도 반응할 수 있는 자동 확장 시스템 autoscaling system 이 있다<br />

면 멋진 일이겠지만 한 달에 겨우 두 번 실행하고 하루 이틀 동안 다운되는 것이 그다지 대수롭<br />

지 않는 리포팅 시스템에는 과도하다. 마찬가지로 온라인 전자 상거래를 위해 서비스의 다운타<br />

임을 없애기 위한 청색/녹색 배포의 방법을 찾는 것은 합당한 일이지만 자사 인트라넷 지식 기<br />

반 시스템을 위해 사용하는 것은 아마 너무 앞서나간 것이다.<br />

얼마나 많은 장애를 감내할 수 있는지와 얼마나 빠른 시스템이 되어야 하는지 아는 것은 여러분<br />

<strong>시스템의</strong> 사용자에 의해 좌우된다. 그것은 결국 여러분이 가장 적합한 기술이 어떤 것인지 파악<br />

하는 데 도움이 된다. 그렇지만 사용자가 항상 정확한 요구 사항을 분명히 표현하는 것은 아니<br />

다. 따라서 여러분은 사용자가 올바른 정보를 뽑아내고 다양한 수준의 서비스 제공에 대한 상대<br />

적 비용을 이해하도록 돕기 위해 질문을 해야 한다.<br />

이전에 언급한 것처럼 이러한 교차기능 요구 사항은 서비스마다 다르다. 그러나 필자는 일반적<br />

인 교차기능 몇 가지를 정의하고 또한 특별한 사용 사례를 위해 그들을 재정의하라고 권한다. 부<br />

하와 장애를 더 잘 처리하기 위해 <strong>시스템의</strong> 확장 방법을 고려해야 한다면 다음 요구 사항을 이해<br />

하는 것에서 출발하라.<br />

응답시간/지연시간<br />

다양한 연산은 얼마나 오래 걸려야 할까? 증가하는 부하가 응답시간에 어떻게 영향을 주는지 이해하기 위해 각<br />

각 다른 수의 사용자로 측정하는 것은 유용할 수 있다. 네트워크의 특성상 항상 이상치가 발생하므로 관찰할 응<br />

답의 특정 백분위수를 목표로 설정하는 것이 유용하다. 목표치는 소프트웨어가 처리할 동시 접속 및 사용자수 또<br />

한 포함해야 한다. 그러므로 여러분은 ‘웹사이트가 초당 200개의 동시 접속수를 처리할 때 응답시간의 90%가<br />

2초 미만을 유지할 것으로 예상됩니다’라고 말할 수 있어야 한다.<br />

가용성<br />

여러분은 서비스가 다운될 것을 예상하는가? 24/7의 연중무휴 서비스로 간주할 수 있는가? 가용성을 측정할 때<br />

어떤 사람은 허용 가능한 다운타임 기간을 보고 싶어 하지만 서비스를 호출하는 사람에게 그 정보가 얼마나 유용<br />

할까? 서비스가 응답하든 안 하든 사용할 수 있어야 한다. 다운타임 기간의 측정은 실제로 사건 기록 리포팅 관<br />

점에서 더 유용하다.<br />

데이터의 내구성<br />

얼마나 많은 데이터 손실이 허용 가능한가? 얼마나 오랜 기간 데이터를 보관해야 하는가? 이 질문은 경우에 따<br />

라 매우 다를 것이다. 예를 들어 여러분은 사용자 세션 로그의 보관 기간은 1년 또는 공간 절약을 위해 그 이하로<br />

선택할 수 있지만 금융 거래 기록은 수년 동안 보관해야 할 수도 있다.<br />

11장 대규모 <strong>마이크로서비스</strong><br />

277


여러분은 이러한 요구 사항을 지속적이며 체계적으로 측정할 방법이 필요하다. 예를 들어 시스<br />

템에 성능 목표 허용치를 보장하기 위해 성능 테스트를 활용하기로 결정할 수 있으며, 실환경에<br />

서도 이러한 성능 통계를 모니터링하고 싶을 것이다.<br />

11.3 기능 분해<br />

회복력 있는 시스템 <strong>구축</strong>에서 가장 중요한 것 중 하나는 안전하게 기능을 분해할 수 있는 능력이<br />

다. 특히 동작 또는 다운 중일 수 있는 다양하고 수많은 <strong>마이크로서비스</strong>에 기능이 확산되어 있을<br />

때는 더 그렇다. 전자 상거래 사이트의 일반적인 웹 페이지를 생각해보자. 그 웹사이트의 다양한<br />

부분이 협업하도록 제 역할을 할 수 있는 몇 개의 <strong>마이크로서비스</strong>가 필요할 것이다. 어떤 마이크<br />

로서비스는 판매될 앨범에 대한 상세 정보를 보여주고 다른 서비스는 가격과 재고 수준을 보여<br />

줄 것이다. 그리고 또 다른 <strong>마이크로서비스</strong>를 통해 쇼핑 카트의 내용물을 표시할 것이다. 이제<br />

이들 <strong>마이크로서비스</strong> 중 하나가 다운되었을 때 전체 웹 페이지를 이용할 수 없게 된다면 우리는<br />

틀림없이 오직 한 서비스만 사용하는 시스템보다 회복력이 떨어지는 시스템을 만든 것이다.<br />

우리는 각 서비스의 장애로 인한 충격을 이해하고 기능을 적절히 분해하는 방법을 생각해야 한<br />

다. 만약 쇼핑 카트 서비스가 가용한 상태가 아니라면 문제는 많겠지만 제품 목록의 웹 페이지는<br />

여전히 보여야 한다. 어쩌면 우리는 쇼핑 카트를 감춰버리거나 곧 정상화될 것임을 알려주는 아<br />

이콘으로 대치해야 할지도 모른다.<br />

하나로 된 모놀리식 애플리케이션에서 우리가 선택할 방안은 그다지 많지 않다. 시스템 상태는<br />

on 또는 off와 같은 이진 값이다. 하지만 <strong>마이크로서비스</strong> <strong>아키텍처</strong>에서는 훨씬 미묘한 상황을<br />

고려해야 한다. 어떤 상황에서도 할 수 있는 올바른 결정은 대개 기술적 결정이 아니다. 쇼핑 카<br />

트가 다운되었을 때 기술적으로 가능한 것이 어떤 것인지 알 수도 있지만 비즈니스 맥락을 이해<br />

하지 못한다면 어떤 행동을 취해야 할지 이해할 수 없을 것이다. 예를 들어 전체 사이트를 닫거<br />

나, 사람들이 제품 목록을 살펴보도록 허용하거나, 쇼핑 카트 컨트롤을 포함하고 있는 UI 일부<br />

분을 주문용 전화번호로 바꿀 수 있다. 그러나 다수의 <strong>마이크로서비스</strong>를 사용하는 모든 고객을<br />

향한 인터페이스나 다수의 하위 협업자 서비스에 의존하는 <strong>마이크로서비스</strong>가 다운되면 어떤 일<br />

이 벌어질지 자문하고 무엇을 해야 할지 알아야 한다.<br />

278 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


교차기능 요구 사항의 관점에서 개별 기능의 심각도를 생각함으로써 우리가 무엇을 할 수 있는<br />

지 훨씬 더 잘 알게 될 것이다. 이제 장애가 발생할 때 우아하게 처리할 수 있도록 기술적인 관점<br />

에서 가능한 일들을 고려해보자.<br />

11.4 <strong>아키텍처</strong> 안전 조치<br />

필자는 무언가 잘못될 때 벌어지는 심각한 파급 효과를 막기 위해 이용하는 몇 가지 패턴을 통<br />

칭하여 <strong>아키텍처</strong> 안전 조치 architectural safety measure 라고 부른다. 이것을 이해하는 것은 필수 사항이<br />

다. 그리고 나쁜 시민 한 명이 시스템 세상 전체를 망가뜨리지 않도록 여러분 시스템에 표준화를<br />

강력히 고려해야 한다. 여러분이 고려해야 할 몇 가지 핵심 안전 조치를 곧 살펴보겠지만, 그전<br />

에 잘못될 수 있는 일들을 설명하기 위해 짧은 이야기를 공유하자.<br />

필자가 온라인 안내 광고 웹사이트를 <strong>구축</strong>하는 프로젝트의 기술팀장이었을 때의 일이다. 그 웹<br />

사이트는 대규모 용량의 트래픽을 처리하고 사업에서 큰 수익을 내고 있었다. 새로운 핵심 애플<br />

리케이션은 안내 광고를 출력하고 [그림 11-1]처럼 종류가 다른 제품에 의해 제공되는 서비스<br />

에 대한 호출의 프록시 기능도 담당했다.<br />

그림 11-1 이전 레거시 애플리케이션을 교살하는 안내 광고 웹사이트<br />

<br />

<br />

<br />

이것은 신규 시스템이 기존 시스템으로 향하는 호출을 가로채서 점진적으로 모두 교체하는 교<br />

살자 애플리케이션의 실사례다. 프로젝트 하에서 필자와 동료들은 구 애플리케이션들을 퇴역시<br />

키고 있었고 가장 용량이 크고 수익이 높은 제품을 우선 교체했지만, 광고의 대부분은 여전히 구<br />

11장 대규모 <strong>마이크로서비스</strong><br />

279


애플리케이션에 의해 제공되고 있었다. 이들 애플리케이션을 통한 검색 수와 수익면에 있어서<br />

아주 긴 꼬리, 즉 롱테일 long tail3 의 형태를 보여주고 있었다.<br />

신규 시스템은 어느 정도의 부하를 처리하며 잠시 동안 매우 잘 동작했다. 그러나 최고치에서 초<br />

당 6,000~7,000개의 요청을 처리했을 때였다. 대부분의 요청은 애플리케이션 앞단에 있는 리<br />

버스 프록시에 캐시되었지만, 이 사이트에서 가장 중요한 기능이라고 할 수 있는 제품 검색은 캐<br />

시되지 않아서 서버 전체를 왕복해야 했다.<br />

평소 점심시간 즈음에 가장 많은 접속이 이루어지는데, 어느 날 아침 시스템이 느려지면서 차례<br />

로 다운되기 시작했다. 새로운 핵심 애플리케이션은 여러 단계로 모니터링되고 있어 각 애플리<br />

케이션 서버 노드의 CPU 사용량이 100%에 도달했는지 잘 보여주고 있었다. 하지만 최고치에<br />

도달하기도 전에 정상 수준을 조금 넘자 단시간에 사이트 전체가 다운되었다.<br />

필자와 동료들은 겨우 원인을 찾아서 시스템을 복구해 놓았다. 가장 낙후되고 제대로 관리되지<br />

않은 하위 광고 시스템 중 하나가 매우 느리게 응답하기 시작한 것이 문제였다. 매우 느린 응답<br />

은 여러분이 경험할 수 있는 가장 나쁜 장애의 유형이다. 차라리 시스템이 전혀 동작하지 않는다<br />

면 문제를 더 빨리 찾아내겠지만 단순히 느려진다면 결국 동작을 포기하지 전까지 한참을 기다<br />

려야 한다. 그러나 장애의 원인이 무엇이든지 간에 통제가 안 된 하위 서비스 하나가 전체 시스<br />

템을 다운시키는 장애 전파에 취약한 시스템을 만든 것은 사실이다.<br />

한 팀이 하위 <strong>시스템의</strong> 문제를 분석하는 동안 나머지 사람은 새로운 애플리케이션에 잘못된 것<br />

이 있는지 살펴보기 시작했고 몇 가지 문제를 찾아냈다. 당시 우리는 하위 시스템과의 커넥션을<br />

처리하기 위해 HTTP 커넥션 풀을 사용하고 있었고 풀 내부의 스레드는 하위 HTTP 호출을 할<br />

때 커넥션 유지를 위한 제한시간, 즉 타임아웃 timeout 이 설정되어 있었다. 타임아웃 자체는 좋은<br />

것이지만 모든 작업자 스레드가 느린 하위 시스템에 의해 타임아웃되는 것이 문제였다. 작업자<br />

스레드가 타임아웃을 기다리는 동안 그 스레드에 대한 더 많은 요청이 커넥션 풀에 유입되었고<br />

모든 작업자 스레드가 가용하지 않은 상황에서 요청들은 실제로 행 hang 이 걸린 상태가 되었다.<br />

필자가 사용한 커넥션 풀 라이브러리는 가용한 작업자 스레드를 기다리며 타임아웃되었지만 타<br />

임아웃은 기본 설정이 비활성화 disabled by default 되어 있었다! 결국 엄청나게 많은 블로킹된 스레<br />

드가 생겨났다. 당시 그 애플리케이션은 어떤 상황에서도 보통 40개의 동시 커넥션을 유지했는<br />

데, 이 상황에서는 5분 만에 커넥션이 최대 800여 개까지 높아져서 결국 시스템이 다운되었다.<br />

3 옮긴이_ 인터넷과 물류 기술의 발달로 다품종 소량 생산된 비주류 상품이 시장 점유율을 높여가는 현상<br />

280 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


설상가상으로 문제가 된 하위 서비스가 제공하는 기능은 고객이 사용하는 전체 기능의 5%도 채<br />

되지 않았고 그보다 훨씬 적은 수익을 내고 있었다. 결론을 말하자면 고장나서 작동하지 않는 시<br />

스템보다 느리게 동작하는 시스템이 훨씬 다루기 힘들다는 것을 우리는 어렵게 습득했다. <strong>분산</strong><br />

시스템에서 지연시간은 매우 중요하다.<br />

커넥션 풀의 타임아웃 설정을 제대로 했더라도 외부의 모든 요청에 대해 하나의 HTTP 커넥션<br />

을 공유하고 있었다는 것은 모든 서비스가 정상인 상태에서도 느린 서비스 하나로 모든 가용한<br />

작업자 스레드가 소진될 수 있다는 것을 의미했다. 문제의 하위 서비스가 정상 상태가 아님이 분<br />

명한데도 우리는 트래픽을 계속 그쪽으로 전송하도록 했다. 그 상황에서 하위 서비스가 복구될<br />

가능성은 희박했기 때문에 실제로 필자와 동료들은 상황을 악화시킨 셈이었다. 결국 우리는 재<br />

발을 막기 위해 세 가지 조치를 취했다. 타임아웃을 올바르게 설정했고, 커넥션 풀을 분리하기<br />

위한 격벽 bulkhead 을 구현했으며, 정상 동작하지 않는 시스템은 애초에 호출하지 않도록 회로 차<br />

단기를 구현했다.<br />

11.5 안티프래질 조직<br />

나심 탈레브 Nassim Taleb4 는 그의 저서 『안티프래질』(와이즈베리, 2013 )에서 실패와 무질서로부<br />

터 얻을 수 있는 혜택에 대해 설명했다. 에이리얼 지틀린 Ariel Tseitlin5 은 넷플릭스의 운영 방식에<br />

대한 안티프래질 조직 6 의 개념을 형성하기 위해 안티프래질을 이용했다.<br />

넷플릭스가 전적으로 AWS 인프라스트럭처에 기반한다는 사실만큼 넷플릭스는 운영 규모로도<br />

유명하다. 그리고 이 두 요소는 장애를 잘 수용해야 한다는 것을 의미한다. 넷플릭스는 장애에<br />

강한 시스템을 보장하기 위해 실제로 장애를 조장하며 이를 극복했다.<br />

몇몇 회사는 유휴 시스템에서 장애를 시뮬레이션하고 다양한 팀이 경연을 펼치는 게임의 날 game<br />

days 을 좋아할 것이다. 필자가 구글에서 일할 때 이것은 다양한 시스템에서 매우 널리 행해졌다.<br />

4 옮긴이_ 전직 투자전문가이자 철학자, 수학자, 베스트셀러 작가로 『블랙스완』(동녁사이언스, 2008), 『행운에 속지마라』(중앙북스,<br />

2010), 『능력과 운의 절묘한 조화』(오늘의책, 2002) 등을 저술했다.<br />

5 옮긴이_ 투자가이자 기업가, 기술 임원으로 제품 전략 및 기획, 팀 빌딩의 경험이 많다. 넷플릭스에서 일할 때 애자일을 기반으로 안티프<br />

래질 팀의 형성 및 운영에 기여했다.<br />

6 http://bit.ly/1e9i40t<br />

11장 대규모 <strong>마이크로서비스</strong><br />

281


필자는 이런 종류의 정기적 연습을 통해 많은 조직이 혜택을 받을 것으로 확신한다. 구글은 서<br />

Disaster Recovery<br />

버 장애를 흉내 내는 단순한 테스트 수준을 넘어 매년 진행하는 장애 복구 테스트<br />

Test (DiRT) 훈련 7 의 일부로 지진과 같은 대규모 재난까지 시뮬레이션한다. 넷플릭스 또한 장애<br />

를 유발하는 프로그램을 작성해서 하루 단위로 실환경에 실행하는 더 공격적인 방법을 취한다.<br />

이들 프로그램 중 가장 유명한 카오스 몽키 Chaos Monkey 는 하루 중 특정 시간 동안 임의로 머신의<br />

전원을 꺼버린다. 결국 실운영 환경에서 이런 사고의 발생 가능성을 인지하는 것은 시스템을 만<br />

드는 개발자들이 실제로 그 사고에 준비하게 만든다. 카오스 몽키는 넷플릭스의 장애를 만드는<br />

봇 bot 인 유인원 부대 Simian Army 의 일부다. 카오스 고릴라 Chaos Gorilla 는 전체 가용성 센터(AWS의<br />

데이터 센터에 해당되는)를 검토하는 데 사용하는 반면 레이턴시 몽키 Latency Monkey 는 머신 간의<br />

느린 네트워크 접속 상황을 시뮬레이션한다. 넷플릭스는 이러한 도구들을 오픈 소스 라이선스 8<br />

하에서 이용하게 했다. 여러분 시스템이 정말로 튼튼한지 알 수 있는 궁극의 테스트는 실환경에<br />

여러분의 유인원 부대를 풀어놓는 것이다.<br />

넷플릭스가 소프트웨어를 통해 장애를 수용하며 조장하고 그 장애에 잘 대응하는 시스템을 <strong>구축</strong><br />

한 것만은 아니다. 넷플릭스는 발생한 장애가 주는 교훈의 중요성과 실수를 해도 비난하지 않는<br />

문화를 수용하는 중요성을 잘 알았다. 각 개발자는 실환경에서 자신의 서비스를 관리할 책임도<br />

있으므로 배우고 진화하는 이 과정에 더욱 적극적으로 참여하게 되었다.<br />

넷플릭스는 장애를 만들고 그 장애에 대응하도록 <strong>구축</strong>함으로써 확장이 잘되고 고객의 요구도<br />

잘 지원하는 시스템을 보장했다.<br />

모두가 구글과 넷플릭스가 한 것처럼 극단적으로 할 필요는 없지만 <strong>분산</strong> 시스템에서 요구되는<br />

마인드셋의 전환을 이해하는 것은 중요하다. 모든 것은 결국 고장나게 되어 있다. 여러분 시스템<br />

이 네트워크(신뢰할 수 없고)와 많은 머신(결국은 고장나는)에 걸쳐 널리 퍼져 있다는 사실은<br />

<strong>시스템의</strong> 취약점을 낮추기보다는 더 높일 것이다. 따라서 여러분이 구글이나 넷플릭스 같은 규<br />

모의 서비스를 제공하려는 것과 관계없이 더욱 <strong>분산</strong>된 <strong>아키텍처</strong>에서 발생할 수 있는 이런 장애<br />

에 대응하기 위한 준비는 아주 중요하다. 그렇다면 우리 시스템에서 발생하는 장애를 처리하기<br />

위해서는 무엇을 해야 할까?<br />

7 http://bit.ly/15CnW3a<br />

8 http://bit.ly/1fsqzaH<br />

282 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


11.5.1 타임아웃<br />

타임아웃은 간과하기 쉽지만 하위 시스템에서 올바르게 사용되는 것이 중요하다. 하위 시스템이<br />

실제로 다운될 때까지 얼마나 오래 기다릴 수 있을까?<br />

호출이 실패했다고 판단하는 데 너무 오래 걸리면 전체 시스템이 느려질 수 있다. 너무 빨리 타<br />

임아웃하면 동작했을지도 모르는 호출을 실패로 고려할 것이다. 타임아웃이 전혀 없다면 하위<br />

시스템이 다운되어 전체 시스템이 중단될 수 있다.<br />

모든 프로세스 경계 외부의 호출에 타임아웃을 넣고 항상 기본 타임아웃 시간을 설정하라. 타임<br />

아웃 발생 시간을 로깅하고 어떤 일이 발생했는지 살펴보며 타임아웃을 적절히 변경하라.<br />

11.5.2 회로 차단기<br />

가정마다 전력 급등으로부터 가전 기기를 보호하기 위한 회로 차단기 Circuit Breaker 가 있다. 전력<br />

이 급등하면 회로 차단기가 내려가 값비싼 가전 기기를 보호할 것이다. 또한 부분적으로 직접 회<br />

로 차단기를 내려서 가전 기기를 안전하게 사용할 수도 있다. 마이클 나이가드 Michael Nygard 의 『릴<br />

리스 잇: 성공적인 출시를 위한 소프트웨어 <strong>설계</strong>와 배치』(위키북스, 2007)에서 이러한 생각이<br />

소프트웨어를 위한 보호 메커니즘으로 얼마나 놀랄만한 일을 하는지 보여준다.<br />

필자가 바로 앞에서 언급한 예를 생각해보자. 기존의 하위 광고 애플리케이션은 결국 에러를 리<br />

턴하기 전까지 매우 느리게 반응하고 있었다. 정상적으로 타임아웃이 되었다 하더라도 오류가<br />

발생하기까지 오랜 시간을 기다릴 것이다. 그런 다음 다른 요청이 유입되면 다시 기다린다. 하위<br />

서비스가 오동작을 하는 것은 충분히 나쁜 일이지만 우리 역시 느리게 만든다.<br />

하위 자원에 대한 특정 수의 요청이 실패한 후 회로 차단기가 끊어지고 이후의 모든 요청은 회로<br />

차단기가 끊어진 상태이므로 바로 실패한다. 특정 시간 이후 클라이언트는 하위 서비스가 복구<br />

되었는지 확인하기 위해 요청 몇 개를 보내고 정상 응답이 오면 회로 차단기를 리셋한다. [그림<br />

11-2]에서 전체 개요를 볼 수 있다.<br />

11장 대규모 <strong>마이크로서비스</strong><br />

283


그림 11-2 회로 차단기의 개요<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

회로 차단기의 구현 방법은 실패한 요청의 의미에 따라 다르다. 하지만 필자가 HTTP 커넥션을<br />

위한 차단기를 구현할 때는 타임아웃이나 5XX HTTP 리턴 코드에 해당되는 호출 실패를 두었<br />

다. 이렇게 해서 하위 자원이 다운되거나 타임아웃되거나 에러를 리턴할 때 특정 임계값에 도달<br />

284 <strong>마이크로서비스</strong> <strong>아키텍처</strong> <strong>구축</strong>


www.hanbit.co.kr<br />

이것이<br />

프로그래밍이다!<br />

저자 직강 동영상 제공!<br />

이것이 안드로이드다<br />

이것이 C언어다<br />

이것이 자바다<br />

진정한 안드로이드 개발자로<br />

이끌어줍니다.<br />

SDK 5.0 롤리팝 호환!<br />

책만 보고,<br />

동영상 강좌로도 만족하지 못했다면 Daum<br />

카페 '슈퍼드로이드'에서 만나요<br />

cafe.daum.net/superdroid<br />

박성근 저 | 1,164쪽 | 45,000원<br />

세상에 없던 새로운<br />

C언어 입문서 탄생!<br />

삼성, LG에서 펼쳐졌던<br />

전설의 명강의를 풀타임 동영상 강좌로!<br />

이보다 더 확실한 방법은 없다, 칠판강의<br />

전체 동영상 강좌 유투브 전격 공개!<br />

http://goo.gl/tJK3Tu<br />

서현우 저 | 708쪽 | 25,000원<br />

가장 중요한 프로그래밍 언어를 하나<br />

배워야 한다면, 결론은 자바다!<br />

중급 개발자로 나아가기 위한 람다식,<br />

JavaFX, NIO 수록<br />

자바의 모든 것을 알려주는 인터넷 강의<br />

궁금한 것은 카페에서!<br />

cafe.naver.com/thisisjava<br />

신용권 저 | 1,224쪽 | 30,000원


www.hanbit.co.kr<br />

지금은<br />

모던 웹 시대!<br />

모던 웹 디자인을 위한<br />

HTML5 +<br />

CSS3 입문<br />

모던 웹을 위한<br />

JavaScript +<br />

jQuery 입문<br />

HTML5 분야 부동의 1위 도서<br />

HTML5 표준안 확정에 맞춘 완전 개정판의 귀환!<br />

HTML5 권고안과 최신 웹 브라우저 환경 대응<br />

윤인성 저 | 624쪽 | 30,000원<br />

자바스크립트에서 제이쿼리, 제이쿼리 모바일까지<br />

한 권으로 끝낸다!<br />

시대의 흐름에 맞춰 다시 쓴 자바스크립트 교과서<br />

윤인성 저 | 980쪽 | 32,000원<br />

모던 웹을 위한<br />

Node.js<br />

프로그래밍<br />

HTML5 +<br />

CSS3 정복<br />

페이스북, 월마트, 링크드인은 왜<br />

Node.js를 선택했는가?<br />

이 물음에 대한 답은 Node.js가 보여주는 빠른 처리 능력 때문이다.<br />

윤인성 저 | 484쪽 | 25,000원<br />

필요한 것만 배워<br />

바로 현장에서 쓰는 HTML5<br />

순서대로 읽으며 실습할 수 있는 HTML5 자습서<br />

김상형 저 | 700쪽 | 32,000원


www.hanbit.co.kr<br />

Hanbit eBook<br />

Realtime<br />

www.hanbit.co.kr/ebook<br />

DRM free!<br />

어떤 디바이스에서도 자유롭게<br />

eBook Oriented!<br />

전자책에 꼭 맞는 최적의 내용과 디자인<br />

Hanbit eBook<br />

Realtime 70<br />

Hanbit eBook<br />

Realtime 49 89<br />

Hanbit eBook<br />

Realtime 90<br />

Hanbit eBook<br />

Realtime 49 92<br />

MFC<br />

프로그래밍<br />

주식분석 프로그램 만들기<br />

김세훈 지음<br />

JavaScript<br />

Promise​<br />

azu​지음 /​주우영​옮김<br />

STOMP와 MQTT로 개발하는 IoT 이연복 지음<br />

모바일/웹 애플리케이션<br />

Mobile and Web Messaging<br />

제프 메스닐 지음 / 조건희 옮김<br />

자바 개발자를 위한<br />

Vert.x<br />

모바일/웹 메시징 애플리케이션 개발


www.hanbit.co.kr<br />

즐거운 상상이 가득! 2015년 화제의 신간<br />

즐거운 상상이 가득! 2015년 화제의 신간<br />

전자부품 백과사전 vol.2<br />

전자부품 백과사전 vol.1<br />

찰스 플랫 지음 / 배지은 옮김 / 30,000원<br />

취미공학에 필요한 핵심 전자부품을<br />

사전식으로 정리한 안내서.<br />

시리즈의 두 번째 도서다.<br />

Zero to Maker<br />

: 누구나 메이커가 될 수 있다<br />

데이비드 랭 지음 / 장재웅 옮김 / 14,000원<br />

전자부품 백과사전 vol.2 찰스 플랫 지음 / 가격미정<br />

일반인에서 메이커로. 날백수에서 무인 잠<br />

수정 된 사나이, 시리즈의 데이비드 두 번째 도서다.<br />

랭의 메이커 도전기.<br />

Zero to Maker<br />

: 누구나 메이커가 될 수 있다<br />

전자부품 백과사전 vol.1<br />

데이비드 랭 지음 / 장재웅 Maker 옮김 / 14,000원 Pro<br />

존 베이첼 지음 / 가격미정<br />

일반인에서 메이커로. 날백수에서 무인 잠<br />

메이커라면 반드시 읽어야 할 필수 계발<br />

수정 회사 CEO가 된 사나이, 데이비드<br />

서. 프로 메이커들과의 인터뷰 및 에세이<br />

랭의 메이커 도전기.<br />

수록.<br />

프로젝트로 배우는 라즈베리 파이 도날드 노리스 지음 / 임지순 옮김<br />

다양한 실전 프로젝트를 통해 라즈베리 파이를 쉽고 재미있게 배워본다.<br />

찰스 플랫 지음 / 배지은 옮김 / 30,000원<br />

처음 시작하는 센서<br />

취미공학에 필요한 핵심 전자부품을<br />

사전식으로 정리한 안내서.<br />

찰스 플랫 지음 / 가격미정<br />

Maker Pro<br />

존 베이첼 지음 / 가격미정<br />

메이커라면 반드시 읽어야 할 필수 계발<br />

키모 카르비넨,<br />

테로 카르비넨 지음<br />

임지순 옮김 / 13,000원<br />

세상을 수치로 읽어내는<br />

부품인 센서를 알려주<br />

는 책. 이 책을 통해 자신<br />

만의 프로젝트에 다양한<br />

처음 시작하는 센서<br />

센서를 사용해보자.<br />

키모 카르비넨,<br />

테로 카르비넨 지음<br />

임지순 옮김 / 13,000원<br />

세상을 수치로 읽어내는<br />

Make: 센서<br />

부품인 센서를 알려주<br />

키모 카르비넨, 테로 카르비<br />

넨, 빌 발토카리 지음 는 책. 이 책을 통해 자신<br />

/ 가격미정<br />

만의 프로젝트에 다양한<br />

필수 전자부품인 센서를<br />

마이크로 컨트롤러 보드 센서를 사용해보자.<br />

에 응용하는 방법을 담<br />

았다.<br />

Make: 센서<br />

키모 카르비넨, 테로 카르비<br />

넨, 빌 발토카리 지음<br />

/ 가격미정<br />

필수 전자부품인 센서를<br />

마이크로 컨트롤러 보드<br />

에 응용하는 방법을 담<br />

았다.


<strong>마이크로서비스</strong> 입문에서 <strong>구축</strong>과 활용까지!<br />

B u i l d i n g M i c r o s e r v i c e s<br />

<strong>마이크로서비스</strong>는 기존 <strong>대용량</strong> <strong>시스템의</strong> 복잡성과 운영·배포·유지보수의 문제점을 해결할 새로운 대안<br />

이다. 이 책은 <strong>마이크로서비스</strong> <strong>아키텍처</strong>의 개념을 설명하고 시스템을 <strong>구축</strong>하는 구체적 방법을 제시한다.<br />

<strong>마이크로서비스</strong> <strong>아키텍처</strong>를 <strong>구축</strong>·관리할 때 고려할 문제와 이에 관한 포괄적 시각과 실용적인 조언을 제<br />

공한다. 지속적 통합을 통해 개별 <strong>마이크로서비스</strong>를 배포하는 과정을 설명하고, 실제로 <strong>마이크로서비스</strong><br />

를 도입한 기업들의 구체적 사례를 소개한다.<br />

1 조직의 목표에 맞게 시스템 <strong>설계</strong>를 정렬하는 <strong>마이크로서비스</strong> 방식<br />

2 운용 중인 레거시 시스템과 서비스의 통합 방안<br />

3 모놀리식 코드베이스의 점진적 분리 방법<br />

4 지속적 통합으로 개별 <strong>마이크로서비스</strong> 배포<br />

5 <strong>분산</strong> 서비스 테스팅과 모니터링의 복잡성 고찰<br />

6 와 모델의 보안 관리<br />

7 <strong>마이크로서비스</strong> <strong>아키텍처</strong> 확장을 위한 도전<br />

<strong>마이크로서비스</strong> <strong>아키텍처</strong>는 매력적이다. 하지만 실제 구현 과정에는 부주의한 개발자라면 피해 갈 수<br />

없는 고통스런 함정이 도사리고 있다. 이 책은 여러분에게 맞는 길을 제시하고 함정을 피하는 방법을<br />

알려줄 것이다.<br />

마틴 파울러, 『리팩토링』 저자<br />

관련 도서<br />

클라우드<br />

시스템을<br />

관리하는<br />

기술<br />

처음<br />

시작하는<br />

AWS<br />

람다<br />

도커 오케<br />

스트레이션<br />

(e-Book)<br />

Docker로<br />

PaaS<br />

구성하기<br />

(e-Book)<br />

개발방법론 / 서버<br />

정가 26,000원

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!