격벽 패턴

Azure

격벽 패턴은 실패에 관대한 애플리케이션 디자인의 한 유형입니다. 격벽 패턴에서 하나가 고장 나더라도 나머지는 정상적으로 작동하도록 애플리케이션의 요소를 여러 풀에 격리합니다. 그것은 배 선체의 단면 파티션(격벽)의 이름을 따서 명명됩니다. 선체가 손상될 경우 손상된 부분만 물로 채워져 배가 가라앉는 것을 방지할 수 있습니다.

컨텍스트 및 문제점

클라우드 기반 애플리케이션은 각 서비스에 하나 이상의 소비자가 있는 여러 서비스를 포함할 수 있습니다. 서비스의 과도한 로드 또는 실패는 모든 서비스 소비자에게 영향을 미칩니다.

게다가 소비자는 여러 서비스에 동시에 요청을 보낼 수 있으며 각 요청마다 리소스를 사용합니다. 소비자가 잘못 구성되거나 응답하지 않는 서비스에 요청을 보내면 클라이언트의 요청으로 사용되는 리소스가 적시에 해제되지 않을 수 있습니다. 서비스에 계속 요청을 보내면 해당 리소스가 소진될 수 있습니다. 예를 들어 클라이언트의 연결 풀이 소진될 수 있습니다. 이때 다른 서비스에 대한 소비자의 요청이 영향을 받습니다. 결국 소비자는 원래 응답하지 않는 서비스뿐만 아니라 다른 서비스에도 더 이상 요청을 보낼 수 없습니다.

동일한 리소스 소진 문제가 여러 소비자가 있는 서비스에 영향을 줍니다. 하나의 클라이언트에서 발생한 많은 요청은 서비스에서 사용 가능한 리소스를 소진할 수 있습니다. 다른 소비자가 더 이상 서비스를 사용할 수 없어 실패가 연속되는 결과를 야기합니다.

해결 방법

소비자 부하 및 가용성 요구 사항에 따라 서로 다른 그룹으로 서비스 인스턴스를 분할합니다. 이렇게 디자인하면 실패를 격리하여 실패가 발생하더라도 일부 소비자에 대한 서비스 기능을 유지할 수 있습니다.

또한 소비자는 한 서비스를 호출하는 데 사용되는 리소스가 다른 서비스 호출에 사용되는 리소스에 영향을 주지 않도록 리소스를 분할할 수 있습니다. 예를 들어 여러 서비스를 호출하는 소비자에게 각 서비스에 대한 연결 풀을 할당할 수 있습니다. 서비스가 실패하게 되면 해당 서비스에 할당된 연결 풀에만 적용되어 소비자는 계속해서 다른 서비스를 사용할 수 있습니다.

이 패턴의 이점은 다음과 같습니다.

  • 소비자 및 서비스를 연속 실패로부터 격리합니다. 소비자 또는 서비스에 영향을 주는 문제는 자체 격벽 내에 격리하여 전체 솔루션의 실패를 방지할 수 있습니다.
  • 서비스 실패가 발생할 경우 일부 기능을 보존할 수 있습니다. 애플리케이션의 다른 서비스 및 기능은 계속 작동합니다.
  • 다른 품질의 소비 애플리케이션 서비스를 제공하는 서비스를 배포할 수 있습니다. 우선 순위가 높은 소비자 풀은 우선 순위가 높은 서비스를 사용하도록 구성할 수 있습니다.

다음 다이어그램은 개별 서비스를 호출하는 연결 풀 주위의 격벽 구조를 보여 줍니다. 서비스 A가 실패하거나 약간의 다른 문제를 야기하는 경우 연결 풀이 격리되어 있으므로 서비스 A에 할당된 스레드 풀을 사용하는 워크로드만 영향을 받습니다. 서비스 B와 C를 사용하는 워크로드는 영향을 받지 않고 중단 없이 계속 작업할 수 있습니다.

격벽 패턴의 첫 번째 다이어그램

다음 다이어그램은 단일 서비스를 호출하는 여러 클라이언트를 보여 줍니다. 각 클라이언트를 별도 서비스 인스턴스에 할당합니다. 클라이언트 1의 너무 많은 요청으로 해당 인스턴스가 과부하됩니다. 각 서비스 인스턴스는 서로 격리되어 있으므로 다른 클라이언트는 호출 작업을 계속할 수 있습니다.

단일 서비스를 호출하는 여러 클라이언트를 보여 주는 다이어그램

문제 및 고려 사항

  • 애플리케이션의 비즈니스 및 기술 요구 사항과 관련하여 파티션을 정의합니다.
  • 서비스 또는 소비자를 격벽으로 분할할 때 비용, 성능 및 관리 효율성 측면에서의 오버헤드뿐만 아니라 기술에서 제공되는 격리 수준을 고려합니다.
  • 보다 정교한 오류 처리 방법을 제공하려면 다시 시도, 회로 차단기 및 패턴 제한을 조합한 격벽을 사용하는 것이 좋습니다.
  • 격벽으로 소비자를 분할할 때 프로세스, 스레드 풀 및 세마포를 사용하는 것이 좋습니다. resilience4jPolly와 같은 프로젝트는 소비자 격벽을 만들기 위한 프레임워크를 제공합니다.
  • 격벽으로 서비스를 분할할 때 별도의 가상 머신, 컨테이너 또는 프로세스에 배포하는 것이 좋습니다. 컨테이너는 리소스 오버헤드가 매우 낮은 적절히 균형 잡힌 리소스 격리를 제공합니다.
  • 비동기 메시지를 사용하여 통신하는 서비스는 다른 큐 집합을 통해 격리할 수 있습니다. 각 큐에는 메시지를 처리하는 전용 인스턴스 집합 또는 큐에서 제거하고 처리를 디스패치하는 알고리즘을 사용하는 단일 인스턴스 집합을 포함할 수 있습니다.
  • 격벽에 대한 세분성 수준을 결정합니다. 예를 들어 여러 파티션에 테넌트를 배포할 경우 각 테넌트를 별도의 파티션에 배치하거나 여러 테넌트를 하나의 파티션에 배치할 수 있습니다.
  • 각 파티션의 성능 및 SLA를 모니터링합니다.

이 패턴을 사용해야 하는 경우

다음 경우에 이 패턴을 사용합니다.

  • 백 엔드 서비스 집합을 사용하는 데 필요한 리소스를 격리하는 경우 특히 서비스 중 하나가 응답하지 않는 경우에도 애플리케이션이 일정 수준의 기능을 제공할 수 있는 경우
  • 표준 소비자로부터 중요한 소비자를 격리하는 경우
  • 연속 실패로부터 애플리케이션을 보호하는 경우

다음 경우에는 이 패턴이 적합하지 않을 수 있습니다.

  • 프로젝트에서 리소스 사용 효율성이 떨어지면 안 되는 경우
  • 복잡성을 추가할 필요가 없는 경우

예제

다음 Kubernetes 구성 파일은 자체 CPU 및 메모리 리소스와 제한을 사용하여 단일 서비스를 실행하는 격리된 컨테이너를 만듭니다.

apiVersion: v1
kind: Pod
metadata:
  name: drone-management
spec:
  containers:
  - name: drone-management-container
    image: drone-service
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "1"

다음 단계