다시 시도 패턴

Azure

실패한 작업을 다시 시도하여 서비스 또는 네트워크 리소스에 연결하려 할 때 애플리케이션을 사용하여 일시적 오류를 처리합니다. 이렇게 하면 애플리케이션의 안정성을 개선할 수 있습니다.

컨텍스트 및 문제점

클라우드에서 실행되는 요소와 통신하는 애플리케이션은 이 환경에서 발생할 수 있는 일시적인 오류에 민감해야 합니다. 오류로는 구성 요소 및 서비스의 순간적인 네트워크 연결 끊김, 서비스의 일시적인 사용 중단, 서비스가 사용 중일 때 발생하는 시간 제한 등이 있습니다.

이러한 오류는 일반적으로 자체적으로 수정되고, 잠시 후 오류를 발생시킨 동작을 반복하면 성공할 수도 있습니다. 예를 들어 많은 수의 동시 요청을 처리하는 데이터베이스 서비스는 워크로드가 줄어들 때까지 추가 요청을 일시적으로 거부하는 제한 전략을 구현할 수 있습니다. 데이터베이스에 액세스하려는 애플리케이션이 연결하지 못할 수 있지만 잠시 후 다시 시도하면 성공할 수도 있습니다.

솔루션

클라우드에서 일시적인 오류가 예상되고 애플리케이션이 우아하고 투명하게 처리하도록 설계되어야 합니다. 이렇게 하면 애플리케이션이 수행하는 비즈니스 작업에 오류가 미칠 수 있는 영향을 최소화할 수 있습니다. 가장 일반적인 디자인 패턴은 재시도 메커니즘을 도입하는 것입니다.

다시 시도 패턴을 사용하여 호스트된 서비스에서 작업을 호출하는 다이어그램

위의 다이어그램은 재시도 메커니즘을 사용하여 호스트된 서비스에서 작업을 호출하는 방법을 보여 줍니다. 미리 정의된 횟수의 시도 후 요청이 실패하는 경우 애플리케이션은 오류를 예외로 처리하고 적절히 처리해야 합니다.

참고 항목

일시적인 오류의 일반적인 특성으로 인해 기본 제공 재시도 메커니즘은 이제 많은 클라이언트 라이브러리 및 클라우드 서비스에서 사용할 수 있으며, 최대 재시도 횟수, 재시도 간의 지연 및 기타 매개 변수에 대한 어느 정도의 구성이 가능합니다. 많은 Azure 서비스에 대한 기본 제공 재시도 지원은 여기에서 확인할 수 있으며 Microsof Entity Framework는 실패한 데이터베이스 작업을 다시 시도하는 기능을 제공합니다.

재시도 전략

애플리케이션이 원격 서비스에 요청을 보내려 할 때 오류를 감지한 경우 다음 전략을 통해 오류를 처리할 수 있습니다.

  • 취소. 오류가 일시적이지 않거나 반복해도 성공 가능성이 없는 것으로 나타나는 오류의 경우, 애플리케이션은 작업을 취소하고 예외를 보고해야 합니다.

  • 즉시 다시 시도합니다. 보고된 특정 오류가 전송되는 동안 네트워크 패킷이 손상되는 것과 같이 비정상적이거나 드문 경우 가장 좋은 작업은 즉시 요청을 다시 시도하는 것입니다.

  • 잠시 후 다시 시도합니다. 더 일반적인 연결 또는 사용 중인 오류 중 하나로 인해 오류가 발생하는 경우 연결 문제가 수정되거나 작업 백로그가 지워지는 동안 네트워크 또는 서비스에 짧은 기간이 필요할 수 있으므로 프로그래밍 방식으로 재시도를 지연하는 것이 좋은 전략입니다. 대부분의 경우 사용 중인 서비스가 계속 오버로드될 가능성을 줄이기 위해 가능한 한 균등하게 애플리케이션의 여러 인스턴스에서 요청을 분산하기 위해 재시도 사이의 기간을 선택해야 합니다.

요청이 여전히 실패하면 애플리케이션은 기다렸다가 다시 시도할 수 있습니다. 필요한 경우 최대 요청 시도 횟수에 도달할 때까지 다시 시도 간 지연 시간을 늘려 이 프로세스를 반복할 수 있습니다. 지연 시간은 오류 유형과 이 지연 시간 동안 수정할 수 있을 가능성에 따라 서서히 또는 대폭 늘릴 수 있습니다.

애플리케이션은 나열된 전략 중 하나와 일치하는 다시 시도 정책을 구현하는 코드에서 원격 서비스에 액세스하려는 모든 시도를 래핑해야 합니다. 여러 서비스에 전송된 요청은 서로 다른 정책이 적용될 수 있습니다.

애플리케이션은 오류 및 실패 작업의 세부 정보를 기록해야 합니다. 이 정보는 작업자에게 유용 합니다. 즉, 후속 재시도 시도가 성공한 작업에 대한 경고가 작업자에게 넘쳐나는 것을 방지하려면 초기 오류를 정보 항목으로 기록하고 마지막 재시도 시도의 실패만 실제 오류로 기록하는 것이 가장 좋습니다. 다음은 이 로깅 모델의 모양에 대한 예입니다.

서비스를 자주 사용할 수 없거나 사용 중인 경우는 서비스가 종종 해당 리소스를 모두 사용했기 때문에 발생합니다. 서비스를 확장하여 이러한 오류 발생 빈도를 줄일 수 있습니다. 예를 들어 데이터베이스 서비스가 지속적으로 과부하가 걸리는 경우 데이터베이스를 분할하고 여러 서버에 부하를 분산하는 것이 유용할 수 있습니다.

문제 및 고려 사항

이 패턴을 구현할 방법을 결정할 때 다음 사항을 고려해야 합니다.

성능에 미치는 영향

다시 시도 정책은 애플리케이션의 비즈니스 요구 사항 및 장애의 특성에 맞게 튜닝해야 합니다. 중요하지 않은 일부 작업의 경우 여러 번 다시 시도하는 것보다 페일 패스트로 처리하여 애플리케이션의 처리량에 영향을 주지 않도록 하는 것이 좋습니다. 예를 들어 원격 서비스에 액세스하는 대화형 웹 애플리케이션의 경우 다시 시도 간 지연 시간을 짧게 하여 몇 번의 다시 시도 후 실패로 처리하고 사용자에게 적절한 메시지(예: “나중에 다시 시도하세요.”)를 표시하는 것이 좋습니다. 배치 애플리케이션의 경우 시도 간 지연 시간을 대폭 늘려 다시 시도 횟수를 증가시키는 것이 더 적절할 수 있습니다.

시도간 지연 시간을 최소화한 적극적인 다시 시도 정책과 많은 다시 시도 횟수는 최대 용량에 근접하거나 최대 용량으로 실행 중인 서비스를 저하시킬 수 있습니다. 계속해서 실패한 작업을 수행하려고 시도하려는 경우 이 다시 시도 정책은 애플리케이션의 응답성에 영향을 줄 수도 있습니다.

많은 여러 번 다시 시도한 후에도 요청이 계속 실패하는 경우, 애플리케이션이 이후 요청이 동일한 리소스로 가지 않도록 하고 즉시 실패를 간단히 보고하도록 하는 것이 좋습니다. 기간이 만료되면 애플리케이션은 한 번 이상의 요청을 임시로 허용하여 요청이 성공했는지 확인할 수 있습니다. 이 전략의 자세한 내용은 회로 차단기 패턴를 참조하세요.

멱등성

작업이 idempotent인지 여부를 고려합니다. idempotent인 경우 다시 시도해도 안전합니다. 그렇지 않은 경우 다시 시도하면 작업이 여러 번 실행되고 의도하지 않은 부작용이 발생할 수 있습니다. 예를 들어 서비스가 요청을 수신하고 요청을 성공적으로 처리하지만, 응답을 보내지 못할 수 있습니다. 이 경우 재시도 논리는 첫 번째 요청이 수신되지 않은 것으로 가정하고 요청을 다시 보낼 수 있습니다.

예외 종류

서비스에 대한 요청은 오류의 성격에 따라 다른 예외에서 발생하는 다양한 원인으로 실패할 수 있습니다. 일부 예외는 신속하게 해결할 수 있는 오류라고 나타내는 반면 다른 예외는 오류가 더 오래 지속될 것이라고 나타냅니다. 예외 형식에 따라 다시 시도 간의 시간을 조정하는 다시 시도 정책에 유용합니다.

트랜잭션 일관성

트랜잭션의 일부인 작업을 다시 시도하는 것이 전체 트랜잭션 일관성에 어떻게 영향을 주는지 고려합니다. 성공 가능성을 최대화하고 모든 트랜잭션 단계를 취소할 필요를 줄이기 위해 트랜잭션 작업을 다시 시도 정책을 세부 조정합니다.

일반 지침

  • 다양한 오류 상태에 대해 다시 시도 코드를 모두 테스트되는지 확인합니다. 애플리케이션의 성능이 나 안정성에 심각하게 영향을 주지 않는지, 서비스와 리소스에 과도한 부하를 주지 않는지, 경합 상태 또는 병목 현상이 발생하지 않는지 확인합니다.

  • 실패한 작업의 전체 컨텍스트를 이해하는 위치에서만 재시도 논리를 구현합니다. 예를 들어 다시 시도 정책이 다시 시도 정책을 포함하는 또 다른 작업을 호출하는 경우, 이 다시 시도 추가 계층으로 처리하는 데 더욱 오래 걸릴 수 있습니다. 이 경우 페일 패스트로 처리하고 호출한 작업에 실패한 이유를 보고하도록 하위 수준 작업을 구성하는 것이 더 나을 수 있습니다. 그런 다음 이 상위 수준 작업은 자체 정책에 따라 실패를 처리할 수 있습니다.

  • 애플리케이션, 서비스 또는 리소스의 기본 문제를 식별할 수 있도록 재시도를 유발하는 모든 연결 오류를 기록합니다.

  • 서비스 또는 리소스에 발생할 수 있는 오류를 조사하여 오류가 오래 지속되거나 터미널이 될 가능성이 있는지 확인합니다. 오류인 경우 해당 오류를 예외로 처리하는 것이 좋습니다. 애플리케이션은 예외를 보고하거나 기록한 다음, 대체 서비스(있는 경우)를 호출하거나 기능을 저하시켜 계속할 수 있습니다. 오래 지속되는 오류를 검색하고 처리하는 방법에 대한 자세한 내용은 회로 차단기 패턴을 참조하세요.

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

원격 서비스와 상호 작용하거나 원격 리소스에 액세스할 때 애플리케이션에서 일시적인 오류를 발생할 수 있는 경우 이 패턴을 사용합니다. 이러한 오류는 단기간만 존재할 것이며, 이전에 실패한 요청을 반복하면 이후 시도에서 성공할 수 있습니다.

이 패턴은 다음과 같은 경우 유용하지 않을 수 있습니다.

  • 애플리케이션의 응답성에 영향을 줄 수 때문에 오류가 오래 지속될 것 같은 경우. 애플리케이션은 실패할 가능성이 있는 요청을 반복하여 시간 및 리소스를 낭비할 수 있습니다.
  • 애플리케이션의 비즈니스 논리의 오류로 인해 발생한 내부 예외 등 일시적인 오류로 인해 발생하지 않은 실패를 처리하는 경우.
  • 시스템에서 확장성 문제를 해결하는 대체 패턴으로 사용. 애플리케이션에서 자주 사용 중 오류가 발생하는 경우 이는 액세스하는 서비스 또는 리소스를 확장해야 함을 의미하기도 합니다.

워크로드 디자인

설계자는 재시도 패턴을 워크로드 디자인에 사용하여 Azure Well-Architected Framework 핵심 요소에서 다루는 목표와 원칙을 해결하는 방법을 평가해야 합니다. 예시:

핵심 요소 이 패턴이 핵심 목표를 지원하는 방법
안정성 디자인 결정은 워크로드가 오작동에 대한 복원력을 갖도록 하고 오류가 발생한 후 완전히 작동하는 상태로 복구 되도록 하는 데 도움이 됩니다. 분산 시스템에서 일시적인 오류를 완화하는 것은 워크로드의 복원력을 개선하기 위한 핵심 기술입니다.

- RE:07 자기 보존
- RE:07 일시적인 오류

디자인 결정과 마찬가지로 이 패턴으로 도입될 수 있는 다른 핵심 요소의 목표에 대한 절충을 고려합니다.

예시

기본 제공 재시도 메커니즘 지원과 함께 Azure SDK를 사용하는 자세한 예제는 .NET 가이드를 사용하여 재시도 정책 구현을 참조하세요.

다음 단계

  • 사용자 지정 재시도 논리를 작성하기 전에 .NET용 Polly 또는 Java용 Resilience4j와 같은 일반 프레임워크를 사용하는 것이 좋습니다.

  • 비즈니스 데이터를 변경하는 명령을 처리할 때 재시도로 인해 작업이 두 번 수행될 수 있으므로 해당 작업이 고객의 신용 카드 청구와 같은 경우 문제가 될 수 있습니다. 이 블로그 게시물에 설명된 Idempotence 패턴을 사용하면 이러한 상황을 처리하는 데 도움이 될 수 있습니다.

  • 신뢰할 수 있는 웹앱 패턴 은 클라우드에서 수렴되는 웹 애플리케이션에 재시도 패턴을 적용하는 방법을 보여 줍니다.

  • 대부분의 Azure 서비스의 경우 클라이언트 SDK에는 기본 제공 재시도 논리가 포함됩니다. 자세한 내용은 Azure 서비스에 대한 다시 시도 지침을 참조하세요.

  • 회로 차단기 패턴. 오류가 오래 지속될 것 같은 경우 회로 차단기 패턴을 구현하는 것이 적절할 수도 있습니다. 재시도 및 회로 차단기 패턴을 결합하면 오류를 처리하는 포괄적인 접근 방식을 제공합니다.