편집자 – 이 7부작 시리즈 기사는 이제 완료되었습니다.
NGINX Plus를 사용하여 마이크로서비스를 구현하는 것에 대한 정보와 더불어 전체 문서 세트를 전자책으로 다운로드할 수도 있습니다. – 마이크로서비스: 설계부터 배포까지 . 그리고 마이크로서비스 참조 아키텍처 와 마이크로서비스 솔루션 페이지 에 대한 시리즈를 확인하세요.
이 글은 마이크로서비스로 애플리케이션을 구축하는 것에 관한 시리즈의 일곱 번째이자 마지막 글입니다. 첫 번째 기사 에서는 마이크로서비스 아키텍처 패턴을 소개하고 마이크로서비스를 사용하는 것의 이점과 단점에 대해 설명합니다. 다음 문서에서는 마이크로서비스 아키텍처의 다양한 측면에 대해 설명합니다. API 게이트웨이<.htmla> 사용, 프로세스 간 통신 , 서비스 검색 , 이벤트 기반 데이터 관리 , 마이크로서비스 배포 등이 있습니다. 이 글에서는 모놀리식 애플리케이션을 마이크로서비스로 마이그레이션하는 전략을 살펴보겠습니다.
이 글 시리즈가 여러분께 마이크로서비스 아키텍처, 그 이점과 단점, 그리고 마이크로서비스 아키텍처를 언제 사용해야 하는지에 대한 이해를 돕기를 바랍니다. 아마도 마이크로서비스 아키텍처가 귀하의 조직에 적합할 수도 있습니다.
하지만 여러분이 대규모의 복잡한 모노리식 애플리케이션을 작업하고 있을 가능성은 매우 높습니다. 매일 애플리케이션을 개발하고 배포하는 일은 느리고 고통스럽습니다. 마이크로서비스는 먼 미래의 천국처럼 보입니다. 다행히도 거대한 지옥에서 벗어날 수 있는 전략이 있습니다. 이 글에서는 모놀리식 애플리케이션을 점진적으로 리팩토링하여 일련의 마이크로서비스로 만드는 방법을 설명합니다.
모놀리식 애플리케이션을 마이크로서비스로 변환하는 프로세스는 애플리케이션 현대화 의 한 형태입니다. 그건 개발자들이 수십 년 동안 해오던 일이에요. 결과적으로 애플리케이션을 마이크로서비스로 리팩토링할 때 재사용할 수 있는 몇 가지 아이디어가 생겼습니다.
사용해서는 안 될 전략 중 하나는 "빅뱅"을 다시 쓰는 것입니다. 그러면 모든 개발 노력을 처음부터 새로운 마이크로서비스 기반 애플리케이션을 구축하는 데 집중해야 합니다. 매력적으로 들리지만, 매우 위험하며 실패로 끝날 가능성이 높습니다. 마틴 파울러가 말했듯 이, "빅뱅을 다시 쓰는 것이 보장하는 것은 바로 빅뱅뿐이다!"
빅뱅 방식으로 다시 작성하는 대신, 모놀리식 애플리케이션을 점진적으로 리팩토링해야 합니다. 점차적으로 마이크로서비스로 구성된 새로운 애플리케이션을 구축하고, 이를 모놀리식 애플리케이션과 함께 실행합니다. 시간이 지남에 따라 모놀리식 애플리케이션에서 구현된 기능의 양은 줄어들어 결국 완전히 사라지거나 단순히 또 다른 마이크로서비스가 됩니다. 이 전략은 고속도로를 시속 70마일로 달리면서 자동차를 정비하는 것과 비슷합니다. 어렵지만 빅뱅을 다시 쓰는 것보다 훨씬 위험하지 않습니다.
마틴 파울러는 이 애플리케이션 현대화 전략을 스트랭글러 애플리케이션 이라고 부릅니다. 이름은 열대우림에서 발견되는 스트랭글러 포도나무(또는 스트랭글러 무화과)에서 유래되었습니다. 교살덩굴은 숲 꼭대기 위의 햇빛에 도달하기 위해 나무 주위로 자랍니다. 때로는 나무가 죽어서 나무 모양의 덩굴만 남습니다. 애플리케이션 현대화도 동일한 패턴을 따릅니다. 우리는 결국 사라질 기존 애플리케이션을 기반으로 마이크로서비스로 구성된 새로운 애플리케이션을 구축할 것입니다.
이를 위해 다양한 전략을 살펴보겠습니다.
구멍의 법칙은 구멍에 빠졌을 때는 파는 것을 멈춰야 한다는 법칙입니다. 이는 모놀리식 애플리케이션이 관리 불가능해질 때 따르기에 좋은 조언입니다. 즉, 거석을 더 크게 만드는 것을 멈춰야 한다는 뜻입니다. 즉, 새로운 기능을 구현할 때 모놀리스에 더 많은 코드를 추가해서는 안 됩니다. 그 대신, 이 전략의 핵심은 새로운 코드를 독립형 마이크로서비스에 넣는 것입니다. 다음 다이어그램은 이 접근 방식을 적용한 후의 시스템 아키텍처를 보여줍니다.
새로운 서비스와 기존 모놀리스 외에 두 가지 다른 구성 요소가 있습니다. 첫 번째는 들어오는 (HTTP) 요청을 처리하는 요청 라우터입니다. 이는 이전 문서<.htmla>에서 설명한 API 게이트웨이와 유사합니다. 라우터는 새로운 기능에 해당하는 요청을 새로운 서비스로 보냅니다. 레거시 요청을 모놀리스로 라우팅합니다.
또 다른 구성 요소는 서비스를 모놀리스와 통합하는 접착 코드입니다. 서비스는 고립되어 존재하는 경우가 거의 없으며 종종 모놀리스가 소유한 데이터에 액세스해야 합니다. 모놀리스나 서비스, 혹은 둘 다에 존재하는 접착 코드는 데이터 통합을 담당합니다. 이 서비스는 모놀리스가 소유한 데이터를 읽고 쓰기 위해 접착 코드를 사용합니다.
서비스는 모놀리스의 데이터에 액세스하는 데 사용할 수 있는 세 가지 전략이 있습니다.
접착 코드는 때때로 부패 방지 계층 이라고도 불립니다. 그 이유는 접착 코드가 기존 모놀리스의 도메인 모델의 개념으로 인해 원래의 도메인 모델이 있는 서비스가 오염되는 것을 방지하기 때문입니다. 접착 코드는 두 가지 다른 모델 사이를 변환합니다. 부패 방지 계층이라는 용어는 에릭 에반스의 필독서인 Domain Driven Design 에 처음 등장했으며 이후 백서 에서 더욱 구체화되었습니다. 부패 방지 대책을 개발하는 것은 쉬운 일이 아닐 수 있습니다. 하지만 거대한 지옥에서 벗어나기 위해서는 하나를 만드는 것이 필수적입니다.
가벼운 서비스로 새로운 기능을 구현하는 데는 몇 가지 이점이 있습니다. 이는 모노리스가 더욱 관리하기 어려워지는 것을 방지합니다. 서비스는 모놀리스와 독립적으로 개발, 배포 및 확장될 수 있습니다. 새로운 서비스를 만들 때마다 마이크로서비스 아키텍처의 이점을 경험할 수 있습니다.
하지만 이런 접근 방식은 모노리스의 문제를 해결하는 데 아무런 도움이 되지 않습니다. 이런 문제를 해결하려면 모놀리스를 분해해야 합니다. 그렇게 하기 위한 전략을 살펴보겠습니다.
모놀리식 애플리케이션을 축소하는 전략은 프레젠테이션 계층을 비즈니스 로직과 데이터 액세스 계층에서 분리하는 것입니다. 일반적인 엔터프라이즈 애플리케이션은 최소한 세 가지 유형의 구성 요소로 구성됩니다.
일반적으로 한 쪽에는 프레젠테이션 로직이 있고 다른 쪽에는 비즈니스 및 데이터 액세스 로직이 명확하게 분리되어 있습니다. 비즈니스 계층에는 비즈니스 로직 구성 요소를 캡슐화하는 하나 이상의 파사드로 구성된 조립형 API가 있습니다. 이 API는 모놀리스를 두 개의 작은 애플리케이션으로 분할할 수 있는 자연스러운 연결 고리입니다. 한 응용프로그램에는 프레젠테이션 계층이 포함되어 있습니다. 다른 애플리케이션에는 비즈니스 및 데이터 액세스 로직이 포함되어 있습니다. 분할 후, 프레젠테이션 로직 애플리케이션은 비즈니스 로직 애플리케이션에 원격 호출을 수행합니다. 다음 다이어그램은 리팩토링 전후의 아키텍처를 보여줍니다.
이런 식으로 모노리스를 분할하면 두 가지 주요 이점이 있습니다. 이를 통해 두 애플리케이션을 서로 독립적으로 개발, 배포하고 확장할 수 있습니다. 특히, 프레젠테이션 계층 개발자는 이를 통해 사용자 인터페이스를 빠르게 반복하고 A/B 테스트 등을 쉽게 수행할 수 있습니다. 이러한 접근 방식의 또 다른 이점은 개발한 마이크로서비스에서 호출할 수 있는 원격 API를 제공한다는 것입니다.
하지만 이런 전략은 부분적인 해결책일 뿐이다. 두 애플리케이션 중 하나 또는 둘 모두가 관리할 수 없는 거대한 덩어리가 될 가능성이 매우 높습니다. 남아 있는 단일체나 단일체들을 제거하려면 세 번째 전략을 사용해야 합니다.
세 번째 리팩토링 전략은 모놀리스 내의 기존 모듈을 독립형 마이크로서비스로 전환하는 것입니다. 모듈을 추출하여 서비스로 전환할 때마다 모놀리스는 줄어듭니다. 모듈을 충분히 변환하면 모놀리스는 더 이상 문제가 되지 않습니다. 완전히 사라지거나 규모가 작아져서 그저 또 다른 서비스로 남게 됩니다.
대규모의 복잡한 모노리식 애플리케이션은 수십 또는 수백 개의 모듈로 구성되며, 이 모든 모듈이 추출 후보입니다. 어떤 모듈을 먼저 변환해야 할지 파악하는 것은 종종 어렵습니다. 좋은 방법은 추출하기 쉬운 몇 개의 모듈로 시작하는 것입니다. 이를 통해 마이크로서비스 전반에 대한 경험과 특히 추출 프로세스에 대한 경험을 얻을 수 있습니다. 그 후에는 가장 큰 이익을 얻을 수 있는 모듈을 추출해야 합니다.
모듈을 서비스로 변환하는 데는 일반적으로 시간이 많이 걸립니다. 모듈은 귀하가 받게 될 이점에 따라 순위를 매겨야 합니다. 자주 변경되는 모듈을 추출하는 것이 좋습니다. 모듈을 서비스로 변환하면 모놀리스와 별도로 개발하고 배포할 수 있으므로 개발 속도가 빨라집니다.
또한 모놀리스의 나머지 부분과 리소스 요구 사항이 크게 다른 모듈을 추출하는 것도 유익합니다. 예를 들어, 메모리 내 데이터베이스가 있는 모듈을 서비스로 전환한 다음, 이를 대용량 메모리가 있는 호스트에 배포하는 것이 유용합니다. 마찬가지로, 많은 CPU를 갖춘 호스트에 서비스를 배포할 수 있으므로, 계산적으로 많은 비용이 드는 알고리즘을 구현하는 모듈을 추출하는 것도 가치가 있을 수 있습니다. 특정한 리소스 요구 사항이 있는 모듈을 서비스로 전환하면 애플리케이션을 훨씬 더 쉽게 확장할 수 있습니다.
어떤 모듈을 추출할지 알아낼 때 기존의 거친 경계(일명 이음매)를 찾는 것이 유용합니다. 이를 통해 모듈을 서비스로 전환하는 것이 더 쉽고 저렴해집니다. 이러한 경계의 예로는 비동기 메시지를 통해 나머지 애플리케이션과만 통신하는 모듈이 있습니다. 해당 모듈을 마이크로서비스로 전환하는 것은 비교적 쉽고 저렴할 수 있습니다.
모듈을 추출하는 첫 번째 단계는 모듈과 모놀리스 사이에 대략적인 인터페이스를 정의하는 것입니다. 모놀리스에는 서비스가 소유한 데이터가 필요하고 그 반대의 경우도 마찬가지이므로 양방향 API일 가능성이 높습니다. 모듈과 나머지 애플리케이션 간의 복잡한 종속성과 세분화된 상호 작용 패턴 때문에 이러한 API를 구현하는 것은 종종 어렵습니다. 도메인 모델 패턴을 사용하여 구현된 비즈니스 로직은 도메인 모델 클래스 간에 수많은 연관이 있기 때문에 리팩토링하기가 특히 어렵습니다. 이러한 종속성을 끊으려면 상당한 코드 변경이 필요한 경우가 많습니다. 다음 다이어그램은 리팩토링을 보여줍니다.
거친 인터페이스를 구현하면 모듈을 독립형 서비스로 전환할 수 있습니다. 그렇게 하려면 모놀리스와 서비스가 IPC( 프로세스 간 통신 ) 메커니즘을 사용하는 API를 통해 통신할 수 있도록 코드를 작성해야 합니다. 다음 다이어그램은 리팩토링 전, 리팩토링 중, 리팩토링 후의 아키텍처를 보여줍니다.
이 예에서 모듈 Z는 추출할 후보 모듈입니다. 해당 구성 요소는 모듈 X에서 사용되고 모듈 Y에서 사용됩니다. 첫 번째 리팩토링 단계는 대략적인 API 쌍을 정의하는 것입니다. 첫 번째 인터페이스는 모듈 X가 모듈 Z를 호출하는 데 사용하는 인바운드 인터페이스입니다. 두 번째 인터페이스는 모듈 Z가 모듈 Y를 호출하는 데 사용하는 아웃바운드 인터페이스입니다.
두 번째 리팩토링 단계에서는 모듈을 독립 실행형 서비스로 전환합니다. 인바운드 및 아웃바운드 인터페이스는 IPC 메커니즘을 사용하는 코드로 구현됩니다. 서비스 검색과 같은 교차적 문제를 처리하는 마이크로서비스 섀시 프레임워크 와 모듈 Z를 결합하여 서비스를 빌드해야 할 가능성이 높습니다.
모듈을 추출하면 모놀리스나 다른 서비스와 독립적으로 개발, 배포, 확장할 수 있는 또 다른 서비스를 얻을 수 있습니다. 서비스를 처음부터 다시 작성할 수도 있습니다. 이 경우, 서비스를 모놀리스와 통합하는 API 코드는 두 도메인 모델 간에 변환되는 부패 방지 계층이 됩니다. 서비스를 추출할 때마다 마이크로서비스 방향으로 한 걸음 더 나아가게 됩니다. 시간이 지남에 따라 모놀리스는 줄어들고 마이크로서비스의 수가 늘어나게 됩니다.
기존 애플리케이션을 마이크로서비스로 마이그레이션하는 프로세스는 애플리케이션 현대화의 한 형태입니다. 애플리케이션을 처음부터 다시 작성해서 마이크로서비스로 전환해서는 안 됩니다. 대신, 애플리케이션을 점진적으로 리팩토링하여 일련의 마이크로서비스로 만들어야 합니다. 사용할 수 있는 전략은 세 가지가 있습니다. 새로운 기능을 마이크로서비스로 구현합니다. 프레젠테이션 구성요소를 비즈니스 및 데이터 액세스 구성요소에서 분리합니다. 그리고 모놀리스의 기존 모듈을 서비스로 변환합니다. 시간이 지남에 따라 마이크로서비스의 수는 늘어나고, 개발팀의 민첩성과 속도도 향상될 것입니다.
편집자 – 이 7부작 시리즈 기사는 이제 완료되었습니다.
NGINX Plus를 사용하여 마이크로서비스를 구현하는 것에 대한 정보와 더불어 전체 문서 세트를 전자책으로 다운로드할 수도 있습니다. – 마이크로서비스: 설계부터 배포까지 . 그리고 마이크로서비스 참조 아키텍처 와 마이크로서비스 솔루션 페이지 에 대한 시리즈를 확인하세요.
게스트 블로거 크리스 리처드슨은 Amazon EC2를 위한 초기 Java PaaS(서비스형 플랫폼)인 CloudFoundry.com 의 창립자입니다. 그는 현재 기업들과 협의해 애플리케이션을 개발하고 배포하는 방식을 개선하기 위해 노력하고 있습니다. 그는 또한 https://microservices.io 에서 마이크로서비스에 관해 정기적으로 블로그를 쓰고 있습니다.
"이 블로그 게시물에는 더 이상 사용할 수 없거나 더 이상 지원되지 않는 제품이 참조될 수 있습니다. 사용 가능한 F5 NGINX 제품과 솔루션에 대한 최신 정보를 보려면 NGINX 제품군을 살펴보세요. NGINX는 이제 F5의 일부가 되었습니다. 이전의 모든 NGINX.com 링크는 F5.com의 유사한 NGINX 콘텐츠로 리디렉션됩니다."