마이크로서비스의 비용과 혜택 (마틴 파울러)

마틴 파울러의 Microservice Trade-Offs의 번역글입니다. 원문의 다른 번역 글도 있으니 참고해주시고, 오역과 논의를 위한 의견은 언제든지 환영입니다. 감사합니다.

머릿말

많은 개발팀이 마이크로서비스 아키텍처 스타일이 모놀리틱 아키텍처보다 훨씬 더 뛰어난 방법이라고 알고 있다. 그러나 다른 팀은 마이크로서비스가 생산성을 저하시키는 짐처럼 여긴다. 다른 아키텍처 스타일처럼 마이크로서비스도 비용과 혜택을 가지고 온다. 합리적인 선택을 위해 마이크로서비스를 이해하고 정확히 전후관계를 따져서 적용해야 한다.

마이크로서비스는 다음과 같은 혜택을 제공한다.

  1. 명확한 모듈 경계: 마이크로서비스는 모듈화 구조를 강조한다. 대규모 팀에서는 특히나 중요하다.
  2. 독립적인 배포: 단순한 서비스 덕에 배포가 더 쉬워지며 자동화로 인해서 실수를 했을 때 시스템 장애의 원인이 될 가능성이 더 적어진다.
  3. 기술 다양성: 마이크로서비스는 다양한 언어, 개발 프레임워크와 데이터 저장 기술을 혼용할 수 있다.

… 그러나 다음과 같은 비용이 따라온다

  1. 분산: 원격 호출은 느리고 항상 실패의 위험을 가지고 있기 때문에 분산 시스템은 개발하기가 더 어렵다.
  2. 최종 정합성(Eventual Consistency): 분산 시스템에서 강력한 정합성을 유지하는 건 정말로 어렵다. 이 말은 모두가 최종 정합성을 관리해야 한다는 뜻이다.
  3. 운영 복잡성: 정기적인 재배포가 발생하는 많은 서비스를 관리하기 위해 성숙된 운영 팀이 필요하다.

명확한 모듈 경계 (Strong Module Boundaries)

마이크로서비스의 첫 번째 가장 큰 혜택은 명확한 모듈 경계다. 이건 중요한 혜택이지만 조금은 아리송하다. 이론적으로는 모놀리틱보다 마이크로서비스가 더 명확한 경계를 갖을 만한 이유가 없기 때문이다.

그렇다면 명확한 모듈 경계가 의미하는 바는 무엇일까? 소프트웨어를 서로 의존하지 않는 소프트웨어의 묶음(chunk)인 모듈로 나누면 좋다는 점에는 대게 동의할 것이라 생각한다. 시스템의 일부를 변경해야 할 때는 변경하고자 하는 시스템의 작은 부분만 이해하면 되고, 그 작은 부분을 정말 쉽게 찾을 수 있도록 모듈이 돌아기를 원할 것이다.좋은 모듈화 구조는 모든 프로그램에서 유용하지만 규모가 기하급수적으로 성장하는 소프트웨어에서는 훨씬 더 중요하다. 양적으로 모듈이 커지고 팀을 개발해나감으로써 중요성이 더 커질지도 모른다.

마이크로서비스를 지지하는 측면에서 콘웨이 법칙(Conways Law)을 간단하게 소개하자면, 이는 소프트웨어 시스템의 구조는 시스템을 만드는 조직의 커뮤니케이션 구조를 투영한다는 개념이다. 대규모 팀, 특히 다른 지역에 기반을 둔 팀이라면 팀 내 커뮤니케이션보다 팀 상호 간의 커뮤니케이션을 더 적은 횟수로, 그리고 더 공식적으로 하도록 만드는 소프트웨어 구조가 중요하다. 마이크로서비스는 커뮤니케이션 방식 중의 하나로 각 팀이 독립적인 단위로 서로 의사소통을 가능케 해준다.

앞서 말했던것처럼 모놀리틱 시스템이 좋은 모듈화 구조가 되지말라는 법은 없다. 그러나 잘된 경우를 본 사람은 거의 없다. 큰 진흙 덩어리(Big Ball of Mud)가 되는 것이 가장 일반적인 아키텍처 패턴이다. 이런 공통적인 모놀리틱의 운명에 대한 좌절감이 몇몇 팀을 마이크로서비스로 향하게 했다. 모듈 경계가 모듈 간의 참조를 막아주기 때문에 모듈 분리가 가능하다. 모놀리틱 시스템의 문제가 바로 장벽을 몰래 넘어가기가 매우 쉽다는 점이다. 이는 기능을 재빨리 얻어내는 단기 전략으로는 유용할 수 있지만 더 심해지면 모듈화 구조를 약화시키고 팀의 생산성을 허비하게 된다. 모듈을 서비스로 분리해 나눠두면 경계가 더 굳어버려 이러한 큰 병을 해결해낼 방법을 찾아내기가 더 어려워진다.

이러한 의존성의 중요한 측면은 영속화 데이터에 있다. 마이크로서비스의 핵심 특성 중 하나가 분산 데이터 관리(Decentralized Data Management)다. 마이크로서비스에서 각 서비스는 자신의 데이터베이스만 관리해야 하며, 다른 서비스는 반드시 서비스의 API를 통해서만 데이터를 가져가야 한다. 이건 대규모 시스템에서 의존성 다루기를 힘들게 만드는 가장 주요한 요인인 데이터베이스 통합(Integration Databases)을 없애준다.

모놀리틱에서 모듈 경계를 확실히 하는 것도 진짜 가능하다는 걸 강조하는 것도 좋지만 그렇게 하려면 훈련이 필요하다. 비슷하게 마이크로서비스를 큰 진흙 덩어리로 만들어 버릴 수도 있지만, 마이크로서비스를 잘못 되게 하려면 더 많은 노력이 필요로 하다. (역: 마이크로서비스에서 경계를 망치는 건 더 어렵다고..정말?) 내 견해로는 마이크로서비스를 사용하면 더 나은 모듈화를 얻을 가능성이 높다고 생각한다. 당신 팀이 잘 훈련되어 있다고 믿고 있겠지만 팀이 커지면서 규율을 지키기가 점점 더 어려워진다. 이렇게 되면 마치 모듈 경계를 유지하는 것이 더 중요한 것처럼 되버려 모듈화의 장점을 잃어버릴 수 있다.

이 장점은 경계가 제대로 되어 있지 않다면 오히려 불리한 조건이 된다. 이는 “모놀리틱을 먼저하자 전략 (Monolith First strategy)“이 중요한 이유 두 가지중 하나이며, 좀더 일찍이 마이크로서비스를 받아들이려고 하는 이들이 도메인을 잘 이해하려는 것만으로도 스트레스틑 받는 이유다.

그러나 지금으로서는 모듈화 관점에서 경고를 마무리할 순 없다. 시스템이 모듈화를 얼마나 잘 유지하냐는 시간이 지난 후에나 제대로 말할 수 있다. 그래서 마이크로서비스가 더 나은 모듈화를 이끌어 내는지 아닌지는 적어도 몇 년에 걸쳐 마이크로서비스 시스템을 보아 왔을때만 제대로 가늠할 수 있다. 더군다나 얼리 어답터는 더 재능이 있는 편이기 때문에 평균적인 팀이 만든 마이크로서비스 시스템에서의 모듈화 효과를 판단하는 시기를 더 늦춰야한다. 평균적인 팀이 만든 평균적인 소프트웨어를 인정해야 하지만, 그렇다 하더라도 이걸 최고 팀이 만들어 낸 결과와 비교하는 것이 아니라 모놀리틱 아키텍처 하에서 만든 소프트웨어 결과와 비교해야 한다. 그렇지 않으면 판단을 흐리는 조건법적 서술이 되버리고 만다.

현재 시점에 내가할 수 있는 최선은 이러한 유형을 사용해본 사람에게 들은 초기 증거로 판단하는 것이다. 그들의 평가에 따르면 마이크로서비스는 모듈 관리를 극단적으로 쉽게 만들어 준다고 한다.

마이크로서비스 시스템을 어떻게 만들어야 하는 지에 대해 좀더 찾아보고 싶다면 Sam Newman의 책이이 중요한 자료가 된다.

한 사례 연구는 특히 흥미롭다. 한 팀이 마이크로서비스 프리미엄(Microservice Preminum)을 얻을만큼 충분히 복잡하지 않은 시스템에서 마이크로서비스를 사용하는 잘못된 선택을 했다. 이 프로젝트는 어려움을 겪었고 도움이 필요해서 많은 사람들을 프로젝트에 투입했다. 이때 마이크로서비스 아키텍처가 도움이 됐다. 빠르게 몰아닥치는 개발자를 시스템이 받아들일 수 있었고, 이 팀은 전형적인 모놀리틱보다 훨씬 더 쉽게 매우 큰 숫자의 팀을 잘 활용할 수 있었다. 모놀리틱에서 기대하는 것 보다 훨씬 더 생산성을 가속화시킬 수 있었고, 결과적으로 이 팀은 일정을 따라 잡을 수 있었다. 모놀리틱으로 계속 진행해서 완성하는 것보다 더 많은 작업 시간으로 들어가는 소프트웨어 비용 때문에 그 결과는 여전히 약간 부정적이지만, 마이크로서비스 아키텍처는 점점 더 많은 지지를 얻고 있다.

분산 (Distribution)

앞서 말했듯이 마이크로서비스는 모듈화 향상시키기 위해 분산 시스템을 사용한다. 그러나 분산 소프트웨어는 큰 단점을 갖고 있는데, 정말로 분산이라는 점이다. ‘분산’이란 카드를 꺼내자마자 오만가지 복잡함에 빠지게 된다. 마이크로서비스 커뮤니티가 분산 객체 이동으로 인한 비용에 순진하게 대응한다고 생각하지 않지만 여전히 복잡하다.

그 중 첫번째는 성능이다. 오늘날 프로세스 내 함수 호출을 성능 핫스팟(hot spot)으로 보는건 매우 드문 일이지만 원격 호출은 느리다. 서비스가 대여섯 번의 원격 서비스를 호출하고, 각 서비스가 또 다른 원격 서비스를 대여섯 번 호출하고 난 후 응답시간은 너무 끔찍해서 말도 안되는 대기시간이 되버린다.

물론 이 문제를 훌륭하게 대처해 완화할 수는 있다. 첫번째로 호출 단위를 키워서 호출 횟수를 줄일 수 있다. 이렇게 하면 프로그래밍 모델이 복잡해지기 때문에 이제 서비스간의 상호작용을 어떻게 묶을지 생각해야 한다. 협력해야 하는 서비스 간에는 적어도 한 번씩 호출이 일어나기 때문에 어느 정도선의 효과밖에 얻을 수 없다.

두 번째 완화 방법은 비동기를 사용하는 것이다. 여섯 번의 비동기 호출을 병렬로 처리하면 전체 호출시간의 합 대신 가장 느린 호출만큼만 느려진다. 이걸로 큰 성능 상의 이득을 얻을 수 있지만, 반대로 또 다른 인지 비용(cognitive cost)이 발생한다. 비동기 프로그래밍은 어렵다. 제대로 해내기 어렵고 디버깅 하기는 더 어렵기 때문이다. 그러나 많은 마이크로서비스 이야기에서는 납득할만한 성능을 얻으려면 비동기가 필요한하다고 말한다.

속도 다음으로는 신뢰성(reliability)이다. 프로세스 내 함수 호출은 잘 돌아가는 걸로 예상하지만 원격 호출은 언제든지 실패할 수 있다. 많은 마이크로서비스에는 훤씬 더 많은 잠재적인 실패 가능성이 있다. 현명한 개발자는 이걸 알고 실패를 대비해 설계한다. 다행스럽게도 비동기 협력에서 필요로 하는 전술은 실패를 처리하기에 알맞고 그 결과 회복력(resiliency)을 높힐 수 있다. 그렇지만 이것이 충분한 보상이 되지는 않기 때문에 모든 원격 호출의 실패 흐름을 이해하기는 여전히 복잡하다.

이어서 분산 컴퓨팅에 대한 두 가지 큰 오해를 살펴보자.

이 문제에는 상당한 경고가 있다. 첫 째로 이러한 이슈 대부분은 모놀리틱이 성장함에 따라 나타난다. 일부 모놀리틱 시스템만이 완전히 독립적으로 실행될 뿐, 대게는 레거시 시스템과 같은 다른 시스템과 함께 동작한다. 모놀리틱 역시 네트워크를 통해 다른 시스템과 상호작용하기 때문에 동일한 문제를 만나게 된다. 이것이 원격 시스템과의 상호작용을 제어하기 위해 마이크로서비스로 좀더 빨리 넘어가고 싶어하는 이유다. 결과적으로 이러한 경험이 도움이 되기 때문에 더 기술력 있는 팀이 분산 문제를 더 잘 다룰 수 있다.

그러나 분산은 항상 비용이다. 나는 항상 분산 카드 꺼내는 걸 주저하며, 너무 많은 사람들이 이 문제를 과소평가 하고 너무 빨리 분산으로 넘어 간다고 생각한다.

최종 정합성 (Eventual Consistency)

나는 당신이 상당한 인내심을 필요로 하는 웹사이트를 경험했을 것이라 확신하다. 무언가를 갱신하고 화면을 다시 리프레쉬하면 갱신한 내용이 사라진다. 일, 이분을 기다렸다가 다시 리프레쉬하면 갱신한 내용이 나오는 그런 사이트 말이다.

이건 매우 신경질나는 사용성(usability) 문제이며 대부분 최종 정합성의 위험 때문에 일어난다. 화면 갱신을 분홍색 노드가 전달 받았지만 다음으로 받은 요청은 초록색 노드가 처리했고, 초록색 노드가 분홍색 노드에서 갱신된 정보를 받을때까지 불일치 시간을 견뎌야 한다. 결국에는 맞춰지겠지만 그때까지는 무언가 잘못됐다며 놀랄 것이다.

이러한 불일치는 충분히 신경질 나는 일이지만 그보다 더 심각해 질 수 있다. 비즈니스 로직이 불일치한 정보에 의해 결정될 처지에 놓일 수 있고, 이런 현상은 무엇이 잘못되고 있는지를 진단하기가 정말 어려울 수 있다. 불일치 시간이 끝나고 한참 후까지 상황 조사가 오랫동안 계속될 수 있기 때문이다.

마이크로서비스에서는 분산 데이터 관리라는 칭찬할만한 고집때문에 최종 정합성 문제가 발생할 수 있다. 모놀리틱에서는 하나의 트랜잭션에서 여러 건을 한 번에 갱신할 수 있다. 마이크로서비스에서 여러 리소스를 갱신이 필요하면 분산 트랜잭션이 있지만 생각만해도 얼굴이 찡그려진다. 그러니 이제는 개발자가 일치성 문제에 대해 알고, 코드가 저질러 버린 일을 후회하기 전에 동기화를 벗어난 시점을 찾아낼 방법을 알고 이해해야 한다.

모놀리틱 세계도 이러한 문제에 자유롭지 못하다. 시스템이 성장함에 따라 성능 향상을 위해 더 많은 캐시 사용을 필요로 하면서 캐시 불일치(cache invalidation)라는 또 다른 어려운 문제가 발생한다. 대부분 애플리케이션은 긴 주기의 데이터베이스 트랜잭션을 피하기 위해 오프라인 잠금을 필요로 한다. 외부 시스템은 트랜잭션 관리자를 함께 사용할수 없기 때문에 갱신을 해야한다. 대게 비즈니스에서는 가용성(availability)을 더 소중하게 여기기 때문에 비즈니스 프로세스는 생각보다 불일치 문제에 훨씬 더 관대하다. (비즈니스 프로세스는 CAP 이론에 대한 본능적인 이해를 오래동안 갖고 있다.)

다른 분산 문제처럼 모놀리틱은 완전하게 불일치 문제를 피할수는 없지만, 그 중에서도 규모가 더 작을 때는 고통을 훨씬 덜 받게 된다.

독립된 배포 (Independent Deployment)

모듈화 경계와 분산 시스템의 복잡성 간의 트레이드오프는 내가 일을 하는 동안 계속 겪어왔다. 그러나 지난 10년 동안 그중 하나는 뚜렷하게 바뀌었는데, 그건 바로 운영에 릴리즈 하는 역할이다. 20세기 운영 릴리즈는 누구에게나 고통스럽고 흔치 않은 일이었다. 주말 밤낮으로 힘들게 움직였다. 무언가의 유용한 기능을 소프트웨어에 추가하기 위해 주말 주간/야간 교대로 일을 했다. 그러나 오늘날 기술력 있는 팀은 훨씬 더 자주 릴리즈를 하며, 많은 조직들이 하루에도 여러번 운영 릴리즈를 할 수 있도록 지속적인 인도(Continuous Delivery)를 실험하고 있다.

마이크로서비스는 첫 번째 포스트 DevOps의 혁신 아키텍처이다.

이러한 변화는 소프트웨어 산업에 엄청난 영향을 주어 왔고, 마이크로서비스 움직임과 아주 관계가 깊다. 몇몇 마이크로서비스 성과는 대규모 모놀리틱을 배포하기 어려운 문제에서 시작되었다. 모놀리틱에서 작은 변화는 전체 배포 실패의 원인이 된다. 마이크로서비스의 핵심 원칙으로 서비스는 컴포넌트(services are components)이기 때문에 독립적인 배포가 가능해야 한다. 그래서 변화가 생겼을 때 작은 서비스만 테스트해서 배포할 수 있다. 작은 배포가 엉망이 되버려도 전체 시스템을 다운시키지 않는다. 결국에는 실패에 대비하도록 설계가 필요했기 때문에 심지어 컴포넌트가 완전하게 실패하더라도 시스템의 다른 영역은 동작을 멈추지 않게 해야 한다. 비록 어떠한 형태의 우아한 성능저하가 일어날지라도 말이다.

이 관계는 양방향이다. 자주 배포를 해야 하는 마이크로서비스는 반드시 함께 배포 활동을 정의해야만 한다. 이것이 빠른 애플리케이션 배포와 인프라스트럭처 프로비저닝이 마이크로서비스의 전제 조건(Microservice Prerequisites)이 되는 이유다. 기본을 넘어서는 무엇이든 지속적인 인도를 적용 해야만 한다.

지속적인 인도의 가장 큰 혜택은 생각과 동작하는 소프트웨어 사이의 주기를 줄여 준다는 점이다. 이렇게하면 조직은 시장 변화에 빠르게 대응할 수 있고, 경쟁자보다 더 빠르게 새로운 기능을 소개할 수 있다.

비록 많은 사람들이 마이크로서비스를 사용하는 이유로 지속적인 배포를 꼽지만 대규모 모놀리틱에서도 역시 지속적으로 배포는 필수다. Facebook과 Essy는 가장 잘 알려진 사례다. 물론, 마이크로서비스 아키텍처가 독립적인 배포를 실패하는 사례도 많다. 여러 서비스가 신중하게 협력해서 배포해야 하기 때문이다.[2] 마이크로서비스에서 지속적인 인도가 훨씬 더 쉽다고 주장하는 많은 사람들의 의견을 들어봤지만 모듈화의 결과로 실용적인 중요성을 얻는 것에 비해서 여기에 확신이 잘 가지 않는다. 비록 자연스런 모듈화가 배포 속도와 연관성이 강하다고 하지만 말이다.

운영상의 복잡성 (Operational Complexity)

신속하게 배포할 수 있는 작은 크기의 독립적인 유닛은 개발에서는 정말 요긴하지만 대여섯 개의 애플리케이션을 수백 개의 작은 마이크로서비스로 나누면 운영에서는 더 큰 부담을 준다. 엄두도 못낼 만큼 급격하게 바뀌는 도구의 무리를 다루기 얼마나 어려운지 많은 조직들은 앞으로 알 수 있을 것이다.

이로 인해 지속적인 인도의 역할이 더욱 부각된다. 지속적인 인도가 모놀리틱에서는 배우기 위해 노력할만한 가치 있는 기술 중 하나지만, 제대로 된 마이크로서비스를 셋업하기 위해서는 필수다. 자동화와 협업 없이 수십 개의 서비스를 제어할 방법은 절대 없다. 이러한 서비스를 관리하고 모니터링하는 요구가 늘어나면서 운영의 복잡성은 증가한다. 다시 말해 모놀리틱 애플리케이션에서 유용한 성숙도 수준은 마이크로서비스와 함께하더라도 여전히 필요하다.

마이크로서비스 지지자는 각 서비스가 더 작기 때문에 더 이해하기 쉽다는 이야기를 좋아한다. 그러나 복잡성을 제거한게 아니라면 위험을 서비스 간의 상호 연결로 이동하는 꼴 밖에 안된다. 이렇게 되면 운영상의 복잡성이 더 증가해서 고통을 받게 된다. 서비스에 퍼져 있는 코드를 디버깅하기 어려워지는 것처럼… 서비스 경계를 잘 선택하면 이러한 문제가 줄어들지만 잘못된 위치를 경계로 선택하면 문제를 더 심각하게 만든다.

이러한 운영 복잡성을 제어하려면 새로운 기술과 도구를 많이 필요로 한다. 그중에서도 기술을 훨씬 더 강조하고 싶다. 도구는 아직 성숙하지 못했지만 본능적으로 도구가 점점 더 좋아질 것이라 알수 있고, 낮은 기술의 장벽은 마이크로서비스 환경에서 더 높아 질 것이다.

하지만 더 나은 기술과 도구가 필요하다는 문제가 운영의 복잡성을 제어하는 데 가장 어려운 부분은 아니다. 기술과 도구를 효과적으로 모두 사용하려면 DevOps 문화를 이해해야 한다. 개발자, 운영자, 그리고 소프트웨어 인도에 관련된 모든 사람들의 협력이 훨씬 더 중요하다. 문화를 변화시키는 건 어렵다. 특히, 더 크고 더 오래된 조직에서는 더 어렵다. 기술력을 올리고 문화를 바꾸지 않으면 모놀리틱 애플리케이션에서는 어지럽혀지는 정도 겠지만, 마이크로서비스 애플리케이션에서는 엄청난 충격을 줄 것이다.

기술 다양성 (Technology Diversity)

각 마이크로서비스는 독립적인 배포 단위기 때문에 각 서비스 안에서 기술 선택은 상당히 자유롭다. 여러 마이크로서비스는 각기 다른 언어로 작성할 수 있으며 다른 라이브러리와 다른 데이터 저장소를 사용할 수 있다. 이로 인해 팀이 각자 일에 적절한 도구를 선택하도록 해주는데, 일부 언어와 라이브러리는 특정한 종류의 문제에 더 적합하기 때문이다.

기술 다양성에 대한 토론의 대부분은 일에 가장 적합한 도구가 무엇인지에 집중되지만, 대게 마이크로서비스의 가장 큰 혜택은 지루한 버전 처리의 문제에 있다. 모놀리틱에서는 한 버전의 라이브러리만을 사용할 수 있으며 업그레이드 문제가 일어나곤 한다. 시스템 일부에서는 새로운 기능을 사용하기 위해 업그레이드를 필요로 하지만, 이로 인해 시스템의 다른 부분을 망가트릴수도 있다. 라이브러리 버전 문제를 다루는 건 코드 베이스가 더 커질수록 기하급수적으로 어려워지는 문제 중 하나다.

수많은 기술의 다양성이 개발 조직을 완전하게 압도해버릴 수 있다는 위험이 있다. 내가 아는 대부분 조직은 제한된 기술 모음을 사용하도록 독려한다. 공통 환경을 작은 포트폴리오로 다지고 서비스를 더 쉽게 만들기 위해 모니터링과 같은 공통의 도구를 제공해 지원한다.

마이크로서비스가 실험을 가능하게 하는 가치를 과소평가하지 말아라. 모놀리틱 시스템에서는 일찍이 언어와 프레임워크를 결정하면 뒤집기 어려웠다. 십년 후에 이러한 결정이 팀을 기술을 능숙하게 다루지 못하는 팀으로 정체시킬 수도 있다. 마이크로서비스는 팀이 새로운 도구를 실험할 수 있게 해주며, 시스템을 점진적으로 마이그레이션할 수 있게 해준다. 그럼으로써 한 번에 하나의 서비스를 더 적합한 고급 기술을 사용할 수 있게 해준다.

두번째 이유 (2차 요인)

주요한 트레이드오프에 대한 생각을 위에서 항목별로 살펴봤다. 여기서부터는 조금 덜 중요하게 생각하는 몇 가지를 더 살펴보겠다.

마이크로서비스 지지자 대부분은 서비스를 확장하기 쉽다고 말한다. 한 서비스가 많은 부하를 받으면 전체 애플리케이션이 아니라 해당 서비스만 확장할 수 있기 때문이다. 그렇지만 나는 전체 애플리케이션을 복사해 확장하는 쿠키 커터(cookie-cutter) 방식에 비해서 이렇게 선택적으로 확장하는 방식이 실제로 더 효율적이라고 확신하는 제대로된 경험을 담은 보고서를 만들어내기 위해 몸무림치고 있다(역주: 아직 정확한 근거를 대기 어렵다).

마이크로서비스는 민감한 데이터를 분리해 데이터를 더 조심히 보호할 수 있게 해준다. 더나아가 마이크로서비스 사이의 트래픽을 모두 안전하게 보장하면 마이크로서비스 접근 방법은 침입으로 부당하게 이용하기 더 어려워 진다. 보안 문제가 중요하게 되면서 이러한 특징은 마이크로서비스 사용을 검토하는 주요한 이유가 됐다. 이렇게 하지 않더라도 민감한 데이터를 다루기 위해 서비스를 분리하는 모놀리틱 시스템도 드물지 않다.

마이크로서비스를 비평하는 사람들은 모놀리틱보다 마이크로서비스 애플리케이션이 훨씬 테스트하기 어렵다고 얘기한다. 분산 애플리케이션의 엄청난 복잡성 때문에 테스트가 어렵운 건 사실이다. 그러나 마이크로서비스를 테스트하기 위한 좋은 접근방법이 있다. 여기서 가장 중요한 건 제대로 테스트를 할 수 있는 원칙을 가지고 있냐다. 모놀리틱과 마이크로서비스 테스트 사이의 차이를 비교하는 건 부차적인 문제다.

요약

아키텍처 스타일에 대한 일반적인 글에서는 항상 일반적인 충고의 제약(Limitations Of General Advice)에 대해 고민하게 된다. 이 글을 읽는다고 당신이 결정을 해버릴 수 없지만, 당신이 고려 해야 하는 다양한 관점을 검토할 수 있도록 도와줄 수 있다. 여기서 각 비용과 혜택은 시스템마다 완전히 다른 중요도를 갖는다. 심지어 비용과 혜택이 뒤바뀔수도 있다 (명확한 모듈 경계는 더 복잡한 시스템에서는 좋지만 단순한 시스템에서는 불리한 조건이 된다). 모든 의사결정은 당신이 처한 상황의 조건을 대입하고, 시스템의 가장 큰 문제 요소를 평가해 특정 상황에서 어떤 영향을 주는지에 따라 결정해야 한다. 게다가 우리의 마이크로서비스 아키텍처의 경험은 상대적으로 제한적이다. 항상 시스템이 성숙한 후에야 아키텍처 괌점에서 의사결정을 평가할 수 있으며, 개발을 시작한 후 몇 년 동안에는 돌아가는 걸 느끼며 배워야 한다. 우리는 아직 오랫동안 지속된 마이크로서비스 아키텍처에 대한 일화를 많이 접해보지 못했다.

마이크로서비스 자료 안내 마이크로서비스에 대해 좀더 많은 정보를 원하면 내가 정리한 마이크로서비스 자료 안내에서 시작해라. 여기에는 마이크로서비스가 무엇이고, 언제, 어떻게, 누구를 위한 것인지에 대한 최고의 정보를 골라놨다.

모놀리틱과 마이크로서비스는 단순한 0, 1 선택이 아니다. 둘 다 명확하지 않은 정의다. 이는 많은 시스템이 경계가 흐릿한 영역에 놓여 있다는 뜻이다. 또한 이 두 분류에 맞지 않는 전혀 다른 시스템도 있다. 나를 포함한 대부분의 사람들은 모놀리틱과 대비되는 마이크로서비스에 대해 얘기한다. 더 일반적인 유형과 대조하는 것이 이해하기 쉽기 때문이다. 하지만 어떠한 분류에도 편안하게 맞지 않는 시스템이 있다는 걸 기억해야 한다. 나는 모놀리틱과 마이크로서비스를 아키텍처 공간의 두개 영역으로 생각한다. 이 둘은 토론을 유익하게 만드는 흥미로운 특징을 보여주기 때문에 가치있는 이름이지만, 아키텍트가 이들을 아키텍처 공간의 포괄적인 구분으로 생각하는 건 합리적이지 못하다.

그렇긴 하지만 널리 받아들이는 것처럼 보이는 보편적인 요점은 마이크로서비스 프리미엄, 즉 마이크로서비스란 더 복잡한 시스템을 구성해야 할 때만 생산성 확보를 목적으로 비용을 부담해야 한다는 것이다. 그렇기 때문에 모놀리틱 아키텍처로 시스템의 복잡성을 관리할 수 있다면 마이크로서비스를 사용하지 말아야 한다.

그러나 마이크로서비스에 대한 대화의 크기가 소프트웨어 프로젝트의 성공과 실패를 이끌어 가는 더 중요한 이슈는 아니라는 걸 잊지 말아야 한다. 팀 내 구성원의 실력, 상호 간의 협력을 얼마나 잘하는지, 도메인 전문가와 커뮤니케이션의 정도와 같은 말랑말랑한 요소가 마이크로서비스를 사용하냐 안하냐보다 훨씬 더 큰 영향을 줄 것이다. 온전히 기술적인 수준에서는 깨끗한 코드, 제대로 테스트하기, 그리고 혁신적인 아키텍처에 주목하는 것과 같은 일에 집중하는 것이 더 중요하다.