마이크로 서비스란 애플리케이션 개발을 위한 아키텍처 스타일을 의미합니다. 마이크로서비스를 사용하면 대규모 애플리케이션을 각각 담당 영역을 가진 독립적인 구성요소로 분할할 수 있습니다. 마이크로서비스 기반 애플리케이션은 단일 사용자 또는 API 요청을 처리하기 위해 여러 내부 마이크로서비스를 호출하여 응답을 작성할 수 있습니다.
마이크로서비스 기반 애플리케이션을 적절하게 구현하면 다음과 같은 목표를 달성할 수 있습니다.
- 다양한 마이크로서비스 간의 강력한 계약을 정의합니다.
- 롤백을 포함한 독립적인 배포 주기가 가능합니다.
- 하위 시스템의 동시 A/B 출시 테스트를 수행합니다.
- 테스트 자동화 및 품질 보증 오버헤드를 최소화합니다.
- 로깅 및 모니터링의 명확성을 개선합니다.
- 세밀한 원가 계산을 제공합니다.
- 애플리케이션의 전체적인 확장성과 안정성을 향상시킵니다.
Google App Engine에는 마이크로서비스 기반 애플리케이션에 적합한 다양한 기능이 있습니다. 이 페이지는 Google App Engine에서 애플리케이션을 마이크로서비스 기반 애플리케이션으로 배포할 때 적용 가능한 권장사항을 설명합니다.
마이크로서비스로서의 App Engine 서비스
App Engine 프로젝트에서는 여러 마이크로서비스를 별도의 서비스(이전의 모듈)로 App Engine에 배포할 수 있습니다. 이러한 서비스에서는 코드가 완전히 격리되어 있습니다. 서비스에서 코드를 실행하는 유일한 방법은 RESTful API 호출 또는 사용자 요청과 같은 HTTP 호출을 통하는 것입니다. 한 서비스의 코드는 다른 서비스의 코드를 직접 호출할 수 없습니다. 코드는 독립적으로 서비스에 배포할 수 있으며 Python, 자바, Go, PHP와 같은 서로 다른 언어로 다양한 서비스를 작성할 수 있습니다. 자동 확장, 부하 분산, 머신 인스턴스 유형은 모두 서비스와 독립적으로 관리됩니다.
서비스에 포함된 버전
또한 각 서비스에서 여러 버전이 동시에 배포될 수 있습니다. 각 서비스에서는 이러한 버전 중 하나가 기본 제공 버전이 됩니다. 하지만 서비스 버전마다 자체 주소가 있으므로, 배포된 모든 서비스 버전에 직접 액세스할 수 있습니다. 이러한 구조로 인해 새 버전의 스모크 테스트, 여러 버전 간의 A/B 테스트, 간소화된 롤포워드 및 롤백 작업 등 활용 가능성이 무한합니다. App Engine 프레임워크는 대부분의 항목을 지원하는 메커니즘을 제공합니다. 이후 섹션에서 이러한 메커니즘을 자세히 설명합니다.
서비스 격리
서비스는 대부분 격리되어 있지만 일부 App Engine 리소스를 공유합니다. 예를 들어 Cloud Datastore, Memcache, 태스크 큐는 모두 App Engine 프로젝트의 서비스 간에 공유되는 리소스입니다. 이러한 공유에는 몇 가지 이점이 있지만 마이크로서비스 기반 애플리케이션에서는 마이크로서비스 간에 코드 및 데이터 격리를 유지하는 것이 중요합니다. 원치 않는 공유를 완화하는 데 유용한 아키텍처 패턴이 있습니다. 이러한 패턴은 이 문서의 뒷부분에서 설명합니다.
프로젝트 격리
격리 수준을 얻기 위해 이러한 패턴을 사용하지 않고 보다 공식적으로 분리하고 싶은 경우 여러 App Engine 프로젝트를 사용할 수 있습니다. 서비스 대신 프로젝트를 사용하는 방식에는 장단점이 있으며, 상황에 따라 절충점을 찾아야 합니다. 여러 프로젝트를 사용하여 얻을 수 있는 장점이 특별히 요구되는 경우 외에는 성능 향상과 관리 오버헤드 최소화를 위해 단일 프로젝트 내에서 여러 서비스를 사용하는 것이 가장 좋습니다. 물론 두 방식을 합친 하이브리드 방식을 선택할 수도 있습니다.
서비스 격리와 프로젝트 격리 비교
다음 표는 마이크로서비스 아키텍처에서 여러 서비스 또는 여러 프로젝트를 사용하는 경우를 비교한 것입니다.
여러 서비스 | 여러 프로젝트 | |
---|---|---|
코드 격리 | 배포된 코드가 서비스와 버전 간에 완전히 독립적입니다. | 배포된 코드가 프로젝트 간, 각 프로젝트의 서비스와 버전 간에 완전히 독립적입니다. |
데이터 격리 |
Cloud Datastore와 Memcache를 서비스 및 버전 간에 공유하지만 네임스페이스를 개발자 패턴으로 사용하여 데이터를 격리할 수 있습니다.
태스크 큐 격리의 경우 user-service-queue-1 과 같이 큐 이름에 대한 개발자 규칙을 사용할 수 있습니다.
|
Cloud Datastore, Memcache, 태스크 큐가 프로젝트 간에 완전히 독립적입니다. |
로그 격리 | 각 서비스(및 버전)에는 함께 볼 수 있지만 독립적인 로그가 포함됩니다. | 특정 프로젝트의 모든 로그를 함께 볼 수 있지만, 각 프로젝트(및 각 프로젝트의 서비스 및 버전)에는 독립적인 로그가 포함됩니다. 여러 프로젝트의 로그는 함께 볼 수 없습니다. |
성능 오버헤드 | 동일 프로젝트의 서비스가 같은 데이터 센터에 배포되므로, HTTP를 사용한 서비스 간 호출에 발생하는 지연 시간이 매우 짧습니다. | 프로젝트가 서로 다른 데이터 센터에 배포될 수 있으므로 HTTP 지연 시간이 증가할 수 있지만, 그렇더라도 Google 네트워크의 성능은 전 세계적으로 뛰어나기 때문에 지연 시간이 짧은 편입니다. |
원가 계산 | 인스턴스-시간(코드 실행을 위한 CPU와 메모리) 비용은 서비스별로 구분되지 않습니다. 전체 프로젝트의 모든 인스턴스-시간이 하나의 단위로 취급됩니다. | 프로젝트별로 비용이 분할되어 있으므로, 각 마이크로서비스 비용을 쉽게 확인할 수 있습니다. |
운영자 권한 | 운영자는 코드를 배포하고, 버전을 롤포워드 및 롤백하고, 프로젝트의 모든 서비스에 대한 로그를 확인할 수 있습니다. 특정 서비스에 대한 액세스를 제한할 방법은 없습니다. | 운영자의 액세스 권한을 각 프로젝트에서 개별적으로 제어할 수 있습니다. |
요청 추적 | Google Cloud Trace를 사용하면 동일 프로젝트에서 요청 및 그에 따른 서비스에 대한 마이크로서비스 요청을 작성된 단일 추적으로 확인할 수 있습니다. 이 기능을 사용하면 성능을 간편하게 조정할 수 있습니다. | Cloud Trace 호출이 동일한 조직 내에 있으면 여러 GCP 프로젝트에서 시각화할 수 있습니다. |
다음 단계
- App Engine에서 마이크로서비스를 사용하여 개발, 테스트, 품질보증, 스테이징, 프로덕션 환경을 만들고 이름을 지정하는 방법을 이해합니다.
- 마이크로서비스 간 통신을 위한 API 설계 권장사항을 알아봅니다.
- 마이크로서비스 성능 권장사항을 알아봅니다.
- 기존 모놀리식 애플리케이션을 마이크로서비스를 사용하는 애플리케이션으로 마이그레이션하는 방법을 알아봅니다.
- 마이크로서비스가 상황에 적합한지 파악합니다. Google 솔루션 아키텍트인 프레스톤 홈즈가 자신의 개인 블로그에 게시한 글을 통해 마이크로서비스에서 발견된 몇 가지 단점들을 확인할 수 있습니다.