마이크로 서비스 아키텍처 스타일

Azure

마이크로 서비스 아키텍처는 작은 자율 서비스 컬렉션으로 구성됩니다. 각 서비스는 독립적이며 제한된 컨텍스트 내에서 단일 비즈니스 기능을 구현해야 합니다. 제한된 컨텍스트는 비즈니스 내의 자연스러운 분할이며 도메인 모델이 존재하는 명시적 경계를 제공합니다.

마이크로서비스 아키텍처 스타일의 논리 다이어그램

마이크로 서비스란?

  • 마이크로 서비스는 작고, 독립적이며, 느슨하게 결합되어 있습니다. 하나의 소규모 개발자 팀이 작성하고 유지 관리할 수 있습니다.

  • 각 서비스는 작은 개발 팀이 관리할 수 있는 개별 코드베이스입니다.

  • 서비스를 독립적으로 배포할 수 있습니다. 팀이 전체 애플리케이션을 다시 빌드한 후 재배치하지 않고도 기존 서비스를 업데이트할 수 있습니다.

  • 서비스가 해당 데이터 또는 외부 상태를 유지해야 합니다. 이는 별도의 데이터 레이어가 데이터 지속성을 처리하는 기존 모델과의 차이점입니다.

  • 서비스가 잘 정의된 API를 사용하여 서로 통신합니다. 각 서비스의 내부 구현 세부 정보는 다른 서비스에서 숨겨집니다.

  • 다중저장소 프로그래밍을 지원합니다. 예를 들어 서비스가 동일한 기술 스택, 라이브러리 또는 프레임워크를 공유할 필요가 없습니다.

서비스 자체 외에도 다음과 같은 몇 가지 다른 구성 요소가 기존 마이크로 서비스 아키텍처에 나타납니다.

관리/오케스트레이션. 이 구성 요소는 노드에 서비스 배치, 실패 식별, 노드 간에 서비스 부하 조정 등의 작업을 담당합니다. 일반적으로 이 구성 요소는 사용자 지정 빌드가 아니라 Kubernetes와 같은 기성 기술입니다.

API 게이트웨이. API 게이트웨이는 클라이언트의 진입점입니다. 클라이언트는 서비스를 직접 호출하는 대신, 호출을 백 엔드의 적절한 서비스에 전달하는 API 게이트웨이를 호출합니다.

API 게이트웨이를 사용할 경우의 장점은 다음과 같습니다.

  • 클라이언트와 서비스가 분리됩니다. 모든 클라이언트를 업데이트하지 않고도 서비스 버전을 관리하거나 서비스를 리팩터링할 수 있습니다.

  • 서비스가 웹 우호적이 아닌 AMQP 등의 메시징 프로토콜을 사용할 수 있습니다.

  • API 게이트웨이는 인증, 로깅, SSL 종료, 부하 분산 등의 다른 교차 기능을 수행할 수 있습니다.

  • 제한, 캐싱, 변환 또는 유효성 검사와 같은 즉시 사용 가능한 정책.

이점

  • 민첩성. 마이크로 서비스는 독립적으로 배포되기 때문에 버그 수정 및 기능 릴리스를 관리하기가 더 쉽습니다. 전체 애플리케이션을 다시 배포하지 않고 서비스를 업데이트할 수 있고, 문제가 발생하면 업데이트를 롤백할 수 있습니다. 기존의 많은 애플리케이션의 경우, 버그가 애플리케이션의 한 부분에서 발견되면 전체 릴리스 프로세스를 차단할 수 있습니다. 버그 수정이 통합, 테스트 및 게시될 때까지 새로운 기능은 보류될 수 있습니다.

  • 집중화된 소규모 팀. 마이크로 서비스는 규모가 작아서 한 기능 팀에서 충분히 구축, 테스트 및 배포할 수 있습니다. 소규모 팀은 민첩성이 높습니다. 대규모 팀은 커뮤니케이션의 속도가 느리고, 관리 오버헤드가 증가하며, 민첩성이 감소되기 때문에 생산성이 떨어지는 경향이 있습니다.

  • 소규모 코드 기준. 모놀리식 애플리케이션의 경우 시간이 경과하면서 코드 종속성이 얽히는 경향이 있습니다. 새 기능을 추가하려면 여러 지점의 코드를 손봐야 합니다. 마이크로 서비스 아키텍처는 코드나 데이터 저장소를 공유하지 않으므로 종속성이 최소화되며 그 결과 새로운 기능을 추가하기 쉽습니다.

  • 기술의 혼합. 팀은 혼합된 기술 스택을 적절히 사용하여 서비스에 가장 적합한 기술을 선택할 수 있습니다.

  • 결함 격리. 개별 마이크로 서비스를 사용할 수 없게 되더라도, 장애를 제대로 처리하도록 업스트림 마이크로 서비스를 설계하면 전체 애플리케이션에 방해가 되지 않습니다. 예를 들어 회로 차단기 패턴을 구현하거나 마이크로 서비스가 비동기 메시징 패턴을 사용하여 서로 통신하도록 솔루션을 디자인할 수 있습니다.

  • 확장성. 서비스는 별도로 확장될 수 있어 전체 애플리케이션 규모를 확장하지 않고도 리소스가 더 많이 필요한 하위 시스템의 규모를 확장할 수 있습니다. Kubernetes와 같은 오케스트레이터를 사용하면 더 높은 수준의 서비스를 단일 호스트에 압축하여 리소스를 보다 효율적으로 활용할 수 있습니다.

  • 데이터 격리. 단일 마이크로 서비스만 영향을 받기 때문에 스키마 업데이트를 수행하는 것이 훨씬 쉽습니다. 모놀리식 애플리케이션에서는 스키마 업데이트가 매우 어려울 수 있습니다. 애플리케이션의 다양한 부분이 모두 동일한 데이터에 영향을 미칠 수 있어서 스키마를 변경하는 것이 위험하기 때문입니다.

과제

마이크로 서비스의 이점은 무료로 제공되지 않습니다. 마이크로 서비스 아키텍처를 시작하기 전에 고려해야 할 몇 가지 과제가 있습니다.

  • 복잡성. 마이크로 서비스 애플리케이션에는 동등한 모놀리식 애플리케이션보다 작동 부분이 더 많습니다. 각 서비스는 더 단순하지만 전체 시스템이 더 복잡합니다.

  • 개발 및 테스트. 다른 종속 서비스에 의존하는 소규모 서비스를 작성하려면 기존의 모놀리식 또는 계층화된 애플리케이션을 작성하는 것과 다른 접근 방식이 필요합니다. 기존 도구는 항상 서비스 종속성 작업에 맞게 설계되지 않습니다. 서비스 경계를 벗어난 리팩터링은 어려울 수 있습니다. 특히 애플리케이션이 빠르게 발전하는 경우 서비스 종속성을 테스트하기도 어렵습니다.

  • 통제 부족. 마이크로 서비스 빌드에 대한 분산 접근 방법에는 장점이 있지만 문제가 발생할 수도 있습니다. 언어와 프레임워크가 너무 많아서 애플리케이션 유지 관리가 어려워질 수 있습니다. 팀의 유연성을 지나치게 제한하지 않고 몇 가지 프로젝트 전체 표준을 적용하는 것이 유용할 수도 있습니다. 특히 로깅과 같은 교차 기능에 해당합니다.

  • 네트워크 정체 및 대기 시간. 다수의 작고 세분화된 서비스를 사용하면 서비스 간 통신이 증가할 수 있습니다. 또한 서비스 종속성 체인이 너무 길어질 경우(서비스 A가 B를 호출하고, B가 C를 호출하고...) 추가 대기 시간이 문제가 될 수 있습니다. API를 신중하게 디자인해야 합니다. 통신량이 과도한 API를 피하고, 직렬화 형식을 고려하고, 큐 기반 부하 평준화와 같은 비동기 통신 패턴을 사용할 영역을 찾아보세요.

  • 데이터 무결성. 각 마이크로 서비스가 자체 데이터 지속성을 담당합니다. 그 결과, 데이터 일관성이 과제가 될 수 있습니다. 가능한 경우 결과적 일관성을 수용합니다.

  • 관리. 마이크로 서비스에 성공하려면 성숙한 DevOps 문화가 필요합니다. 전체 서비스의 상관관계 로깅이 까다로울 수 있습니다. 일반적으로 로깅은 단일 사용자 작업에 대한 여러 서비스 호출을 상호 연결해야 합니다.

  • 버전 관리. 서비스 업데이트로 인해 종속된 서비스가 손상되지 않아야 합니다. 언제든지 여러 서비스가 업데이트될 수 있으므로 신중하게 디자인하지 않으면 이전 버전 또는 이후 버전과의 호환성 문제가 발생할 수 있습니다.

  • 기술 수준. 마이크로 서비스는 고도로 분산된 시스템입니다. 팀이 성공을 위한 기술과 경험을 가지고 있는지 신중하게 평가합니다.

모범 사례

  • 비즈니스 도메인을 중심으로 서비스를 모델링합니다.

  • 모든 것을 분산합니다. 개별 팀이 서비스 디자인 및 빌드를 담당합니다. 코드 또는 데이터 스키마를 공유하지 않도록 합니다.

  • 데이터 스토리지가 데이터를 소유하는 서비스의 프라이빗용이어야 합니다. 각 서비스 및 데이터 형식에 가장 적합한 스토리지를 사용합니다.

  • 서비스가 잘 디자인된 API를 통해 통신합니다. 구현 세부 정보가 누출되지 않도록 합니다. API는 서비스의 내부 구현이 아니라 도메인을 모델링해야 합니다.

  • 서비스 간의 결합을 피합니다. 결합의 원인에는 공유 데이터베이스 스키마, 엄격한 통신 프로토콜 등이 포함됩니다.

  • 인증, SSL 종료 등의 교차 문제를 게이트웨이에 오프로드합니다.

  • 도메인 정보를 게이트웨이에서 숨깁니다. 게이트웨이는 비즈니스 규칙 또는 도메인 논리를 몰라도 클라이언트 요청을 처리하고 라우트해야 합니다. 그러지 않으면 게이트웨이가 종속성이 되며 서비스 간에 결합이 발생할 수 있습니다.

  • 서비스에 느슨한 결합 및 높은 기능 응집력이 있어야 합니다. 함께 변경될 가능성이 큰 기능은 함께 패키지하고 배포해야 합니다. 개별 서비스에 상주할 경우, 한 서비스가 변경되면 다른 서비스를 업데이트해야 하므로 해당 서비스가 긴밀하게 결합됩니다. 두 서비스 간의 과도한 통신량은 긴밀한 결합과 낮은 응집력의 증상일 수 있습니다.

  • 실패를 격리합니다. 복원 전략을 사용하여 한 서비스 내의 실패가 계단식으로 연속되지 않도록 합니다. 복원력 패턴신뢰할 수 있는 애플리케이션 디자인을 참조하세요.

다음 단계

Azure에서 마이크로 서비스 아키텍처를 빌드하는 방법에 대한 자세한 지침은 Azure에서 마이크로 서비스 설계, 구축 및 운영을 참조하세요.