안티패턴: 캐시 오류 응답

현재 Apigee Edge 문서가 표시되고 있습니다.
Apigee X 문서로 이동
정보

캐싱은 데이터를 나중에 참조할 수 있도록 캐시라는 스토리지 영역에 데이터를 임시로 저장하는 프로세스입니다. 데이터를 캐싱하면 다음의 이유로 상당한 성능 이점이 제공됩니다.

  • 데이터 검색 속도 향상
  • 데이터 재생이 반복되지 않도록 처리 시간 단축
  • API 요청이 백엔드 서버에 도달하지 못하도록 하여 백엔드 서버의 오버헤드 감소
  • 시스템/애플리케이션 리소스의 활용도 향상
  • API 응답 시간 개선

너무 자주 변경되지 않는 데이터에 자주 액세스해야 할 때마다 캐시를 사용하여 이 데이터를 저장하는 것이 좋습니다.

Apigee Edge는 지속성과 빠른 검색을 위해 런타임에 캐시에 데이터를 저장하는 기능을 제공합니다. 캐싱 기능은 PopulateCache 정책, LookupCache 정책, InvalidateCache 정책, ResponseCache 정책을 통해 제공됩니다.

이 섹션에서는 응답 캐시 정책을 살펴보겠습니다. Apigee Edge 플랫폼의 응답 캐시 정책을 사용하면 백엔드 서버의 응답을 캐시할 수 있습니다. 클라이언트 애플리케이션이 동일한 백엔드 리소스에 반복적으로 요청을 수행하고 리소스가 정기적으로 업데이트된다면 이 정책을 사용하여 이러한 응답을 캐시할 수 있습니다. Response Cache 정책은 캐시된 응답을 반환하는 데 도움이 되므로 백엔드 서버로 불필요한 요청을 전달하는 것을 방지합니다.

Response Cache 정책의 이점은 다음과 같습니다.

  • 백엔드에 도달하는 요청 수 감소
  • 네트워크 대역폭 감소
  • API 성능 및 응답 시간 개선

안티패턴

ResponseCache 정책을 사용하면 기본적으로 가능한 상태 코드가 있는 HTTP 응답을 캐시할 수 있습니다. 즉, 성공 및 오류 응답을 모두 캐시할 수 있습니다.

다음은 기본 구성이 적용된 응답 캐시 정책의 샘플입니다.

<!-- /antipatterns/examples/1-1.xml -->
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ResponseCache async="false" continueOnError="false" enabled="true" name="TargetServerResponseCache">
  <DisplayName>TargetServer ResponseCache</DisplayName>
  <CacheKey>
    <Key Fragment ref="request.uri" /></CacheKey>
    <Scope>Exclusive</Scope>
    <ExpirySettings>
      <TimeoutInSec ref="flow.variable.here">600</TimeoutInSec>
    </ExpirySettings>
  <CacheResource>targetCache</CacheResource>
</ResponseCache>

Response Cache 정책은 기본 구성에서 오류 응답을 캐시합니다. 하지만 다음과 같은 이유로 부정적인 영향에 대해 고려하지 않은 채로 오류 응답을 캐시하는 것은 바람직하지 않습니다.

  • 시나리오 1: 알 수 없는 일시적 실패로 오류가 발생하며 문제가 해결된 후에도 캐싱으로 인해 계속해서 오류 응답을 보낼 수 있습니다.

    OR

  • 시나리오 2: 오류가 일정 기간 동안 관찰되고, 문제가 해결된 후 응답을 캐싱하지 않도록 코드를 수정해야 합니다.

이 두 가지 시나리오를 자세히 설명하겠습니다.

시나리오 1: 일시적인 백엔드/리소스 실패

백엔드 서버에서 오류가 발생한 이유는 다음과 같습니다.

  • 일시적인 네트워크 오류
  • 백엔드 서버가 매우 바빠 일시적인 기간 동안 요청에 응답할 수 없음
  • 요청한 백엔드 리소스가 일시적인 기간 동안 제거되거나 사용할 수 없음
  • 일시적인 기간 동안 서버의 처리 시간이 길어서 백엔드 서버의 응답이 느림

이러한 경우 모두 알 수 없는 기간에 오류가 발생한 후 성공적인 응답을 받기 시작할 수 있습니다. 오류 응답을 캐시하면 백엔드 서버의 문제가 해결되어도 Apigee에서 오류 응답을 사용자에게 계속 보낼 수 있습니다.

시나리오 2: 오래되었거나 수정된 백엔드/리소스 실패

백엔드의 오류가 일정 기간 동안 발생했다고 가정해 보겠습니다. 예를 들어 다음 상황 중 하나에 해당합니다.

  • 특정 백엔드 리소스를 1시간 동안 사용할 수 없습니다.

    OR

  • 갑작스러운 사이트 장애, 확장 문제, 유지보수, 업그레이드 등으로 인해 백엔드 서버가 24시간 동안 삭제되거나 사용할 수 없습니다.

이 정보를 사용하여 응답 캐시 정책에서 캐시 만료 시간을 적절하게 설정하여 오류 응답을 오랜 시간 동안 캐시하지 않도록 할 수 있습니다. 하지만 백엔드 서버/리소스를 다시 사용할 수 있게 되면 오류 응답이 캐시되지 않도록 정책을 수정해야 합니다. 이는 백엔드 서버에서 일시적인 일회성 오류가 발생하는 경우 응답을 캐시하여 위의 시나리오 1에서 설명한 것과 같은 문제를 초래하기 때문입니다.

영향

  • 캐싱 오류가 발생하면 백엔드 서버에서 문제가 해결된 후에도 오류 응답이 전송될 수 있습니다.
  • 사용자는 백엔드 서버에서 오류 응답을 캐싱하는 것이 문제의 원인임을 알지 못하고 문제의 원인을 해결하기 위해 많은 시간을 보낼 수 있습니다.

권장사항

  • 오류 응답을 응답 캐시에 저장하지 않습니다. 오류 응답이 캐시되지 않도록 아래 코드 스니펫에서와 같이 ResponseCache 정책에서 <ExcludeErrorResponse> 요소가 true로 설정되어 있는지 확인합니다. 이 구성을 사용하면 성공 코드가 수정되지 않는 한 기본 성공 코드 200~205의 응답만 캐시됩니다.
    <!-- /antipatterns/examples/1-2.xml -->
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ResponseCache async="false" continueOnError="false" enabled="true" name="TargetServerResponseCache">
      <DisplayName>TargetServerResponseCache</DisplayName>
      <CacheKey>
        <KeyFragment ref="request.uri" />
      </CacheKey>
      <Scope>Exclusive</Scope>
      <ExpirySettings>
        <TimeoutinSec ref="flow.variable.here">600</TimeoutinSec>
      </ExpirySettings>
      <CacheResource>targetCache</CacheResource>
      <ExcludeErrorResponse>true</ExcludeErrorResponse>
    </ResponseCache>
    
  • 특정 이유로 오류 응답을 캐시해야 하는 경우 가능한 경우 실패가 관찰되는 최대/정확한 시간을 결정할 수 있습니다.
    • 오류가 표시될 수 있는 시간보다 오래 오류 응답을 캐시하지 않도록 만료 시간을 적절하게 설정합니다.
    • ResponseCache 정책을 사용하여 <ExcludeErrorResponse> 요소 없이 오류 응답을 캐시합니다.

    백엔드 서버 오류가 일시적이지 않은 것이 확실한 경우에만 이 작업을 수행합니다.

  • Apigee에서는 백엔드 서버에서 5xx 응답을 캐시하지 않는 것을 권장합니다.