안티패턴: MaxFailures가 0이 아닌 값으로 설정된 단일 대상 서버로 부하 분산

ApigeeApigee Hybrid 문서입니다.
Apigee Edge 문서 보기

TargetEndpoint 구성은 Apigee가 백엔드 서비스 또는 API에 연결하는 방법을 정의합니다. 백엔드에서 요청을 보내고 응답을 수신합니다. 백엔드 서비스는 HTTP/HTTPS 또는 NodeJS 서버일 수 있습니다.

TargetEndpoint의 백엔드 서비스는 다음 방법 중 하나로 호출할 수 있습니다.

  • HTTP 또는 HTTPS 서버에 대한 직접 URL
  • TargetServer 구성

마찬가지로 ServiceCallout 정책을 사용하여 API 프록시 흐름에서 외부 서비스를 호출할 수 있습니다. 이 정책은 정책 자체에서 직접 또는 TargetServer 구성을 사용하여 HTTP/HTTPS 대상 URL을 정의하도록 지원합니다.

TargetServer 구성

TargetServer 구성은 구체적인 엔드포인트 URL을 TargetEndpoint 구성 또는 서비스 콜아웃 정책에서 분리합니다. TargetServer는 TargetEndpoint의 URL 대신 이름으로 참조됩니다. TargetServer 구성은 백엔드 서비스의 호스트 이름, 포트 번호, 기타 세부정보를 가집니다.

다음은 샘플 TargetServer 구성입니다.

<TargetServer name="target1">
  <Host>www.mybackendservice.com</Host>
  <Port>80</Port>
  <IsEnabled>true</IsEnabled>
</TargetServer>

TargetServer를 사용하면 환경마다 다른 구성을 사용할 수 있습니다. LoadBalancer를 사용하여 TargetEndpoint/Service 콜아웃 정책을 하나 이상의 이름이 지정된 TargetServer로 구성할 수 있습니다. 부하 분산을 기본적으로 지원함으로써 구성된 백엔드 서버 인스턴스 간 API 가용성과 장애 조치가 개선됩니다.

다음은 TargetServer를 사용하는 샘플 TargetEndpoint 구성입니다.

<TargetEndpoint name="default">
    <HTTPTargetConnection>>
      <LoadBalancer>
        <Server name="target1"/>
        <Server name="target2"/>
      </LoadBalancer>
    </HTTPTargetConnection>
</TargetEndpoint>

MaxFailures

MaxFailures 구성은 대상 서버에 대한 최대 요청 실패 횟수를 지정합니다. 이후에는 대상 서버가 다운된 것으로 표시되고 모든 후속 요청의 순환에서 삭제됩니다.

MaxFailures가 지정된 구성 예시:

<TargetEndpoint name="default">
    <HTTPTargetConnection>
      <LoadBalancer>
        <Server name="target1"/>
        <Server name="target2"/>
        <MaxFailures>5</MaxFailures>
      </LoadBalancer>
    </HTTPTargetConnection>
</TargetEndpoint>

위의 예시에서 'target1'에 대한 요청 5개가 연속적으로 실패하면 순환에서 'target1'이 삭제되고 모든 후속 요청은 target2로만 전송됩니다.

안티패턴

MaxFailures가 0이 아닌 값으로 설정된 TargetEndpoint 또는 Service Callout 정책의 LoadBalancer 구성에 단일 TargetServer가 있는 것은 부정적인 영향을 줄 수 있으므로 권장되지 않습니다.

MaxFailures가 5(0이 아닌 값)로 설정된 'target1'이라는 단일 TargetServer가 있는 다음 샘플 구성을 살펴보겠습니다.

<TargetEndpoint name="default">
  <HTTPTargetConnection>
      <LoadBalancer>
        <Algorithm>RoundRobin</Algorithm>
        <Server name="target1" />
        <MaxFailures>5</MaxFailures>
      </LoadBalancer>
  </HTTPTargetConnection>

TargetServer 'target1'에 대한 요청이 5번 실패하면(MaxFailures에 지정된 숫자) TargetServer가 순환에서 삭제됩니다. 장애 조치할 다른 TargetServer가 없으므로 이 구성이 포함된 API 프록시에 대한 모든 후속 요청은 503 Service Unavailable 오류와 함께 실패합니다.

TargetServer 'target1'이 다시 정상 상태로 돌아가고 성공적인 응답을 보낼 수 있는 경우에도 API 프록시에 대한 요청이 계속해서 503 오류를 반환합니다. 대상이 다시 실행되고 나서도 Apigee가 TargetServer를 다시 자동으로 순환시키지 않기 때문입니다. 이 문제를 해결하려면 Apigee에서 TargetServer를 다시 순환시키도록 API 프록시를 재배포해야 합니다.

Service Callout 정책에 동일한 구성을 사용하는 경우 TargetServer 'target1'에 대한 요청이 5번 실패하면 API 요청이 500 오류를 받게 됩니다.

영향

MaxFailures가 0이 아닌 값으로 설정된 TargetEndpoint 또는 Service Callout 정책의 LoadBalancer 구성에서 단일 TargetServer를 사용하면 다음과 같은 결과가 발생합니다.

  • API 프록시가 재배포될 때까지 계속해서 API 요청이 503/500 오류와 함께 실패합니다(최대 MaxFailures에 대해 요청이 여러 번 실패한 뒤).
  • 까다롭고 문제의 원인을 진단하는 데 시간이 오래 걸려 중단 시간이 더 길어집니다(이 안티패턴에 대한 사전 지식 없이).

모범 사례

  1. 가용성을 높이기 위해 LoadBalancer 구성에 2개 이상의 TargetServer가 있습니다.
  2. MaxFailures가 0이 아닌 값으로 설정된 경우 항상 Health Monitor를 정의합니다. 오류 횟수가 MaxFailures에 지정된 수에 도달하면 타겟 서버가 순환에서 삭제됩니다. HealthMonitor를 사용하면 대상 서버를 다시 사용할 수 있을 때 TargetServer가 순환에 들어가도록 하므로 프록시를 재배포할 필요가 없습니다.

    Apigee가 대상 서버에 연결하는 데 사용하는 번호와 동일한 포트 번호로 상태 확인이 수행되도록 하려면 <TCPMonitor> 아래 <Port> 하위 요소를 생략하는 것이 좋습니다(TargetServer 포트와 다르지 않는 한). 기본적으로 <Port>는 TargetServer 포트와 동일합니다.

    HealthMonitor를 사용한 샘플 구성:

    <TargetEndpoint name="default">
      <HTTPTargetConnection>
        <LoadBalancer>
          <Algorithm>RoundRobin</Algorithm>
          <Server name="target1" />
          <Server name="target2" />
          <MaxFailures>5</MaxFailures>
        </LoadBalancer>
        <Path>/test</Path>
        <HealthMonitor>
          <IsEnabled>true</IsEnabled>
          <IntervalInSec>5</IntervalInSec>
          <TCPMonitor>
            <ConnectTimeoutInSec>10</ConnectTimeoutInSec>
          </TCPMonitor>
        </HealthMonitor>
      </HTTPTargetConnection>
    </TargetEndpoint>
  3. 하나의 TargetServer만 있으며 HealthMonitor가 사용되지 않는 경우 LoadBalancer 구성에서 MaxFailures를 지정하지 않습니다.

    MaxFailures의 기본값은 0입니다. 즉, 이 경우 Apigee는 항상 각 요청의 대상에 연결을 시도하며 순환에서 대상 서버를 절대 삭제하지 않습니다.

추가 자료