Azure 서비스에 대한 다시 시도 지침

대부분의 Azure 서비스 및 클라이언트 SDK는 재시도 메커니즘을 제공합니다. 그러나 서비스마다 특성 및 요구 사항이 다르기 때문에 이러한 메커니즘을 서로 다르므로 각 재시도 메커니즘은 특정 서비스에 맞게 조정됩니다. 이 가이드에서는 대부분의 Azure 서비스를 위한 재시도 메커니즘 기능을 요약하고 해당 서비스를 위한 재시도 메커니즘을 사용, 적용 또는 확장하는 데 도움이 되는 정보를 제공합니다.

일시적인 오류 처리, 서비스와 리소스에 대해 연결 및 작업 재시도에 대한 일반 지침은 재시도 지침을 참조하세요.

다음 표에는 이 지침에서 설명하는 Azure 서비스에 대한 재시도 기능이 요약되어 있습니다.

서비스 재시도 기능 정책 구성 범위 원격 분석 기능
Microsoft Entra ID MSAL 라이브러리의 기본 MSAL 라이브러리에 포함 내부 없음
Azure Cosmos DB 서비스의 네이티브 구성할 수 없음 전역 TraceSource
Data Lake 저장소 클라이언트의 네이티브 구성할 수 없음 개별 작업 없음
Event Hubs 클라이언트의 네이티브 프로그래밍 방식 클라이언트 없음
IoT Hub 클라이언트 SDK의 네이티브 프로그래밍 방식 클라이언트 없음
Azure Cache for Redis 클라이언트의 네이티브 프로그래밍 방식 클라이언트 TextWriter
검색 클라이언트의 네이티브 프로그래밍 방식 클라이언트 ETW 또는 사용자 지정
Service Bus 클라이언트의 네이티브 프로그래밍 방식 네임스페이스 관리자, 메시징 팩터리 및 클라이언트 ETW
Service Fabric 클라이언트의 네이티브 프로그래밍 방식 클라이언트 없음
ADO.NET을 사용하는 SQL Database Polly 선언적 방식 및 프로그래밍 방식 코드의 단일 문 또는 블록 사용자 지정
Entity Framework를 사용하는 SQL Database 클라이언트의 네이티브 프로그래밍 방식 AppDomain에 따라 전역 없음
Entity Framework Core를 사용하는 SQL Database 클라이언트의 네이티브 프로그래밍 방식 AppDomain에 따라 전역 없음
Storage 클라이언트의 네이티브 프로그래밍 방식 클라이언트 및 개별 작업 TraceSource

참고

대부분의 Azure 기본 제공 재시도 메커니즘에서는 현재 다른 유형의 오류 또는 예외에 대해 서로 다른 재시도 정책을 적용할 방법이 없습니다. 최적의 평균 성능 및 가용성을 제공하는 정책을 구성해야 합니다. 정책을 미세 조정하는 한 가지 방법은 로그 파일을 분석하여 발생하는 일시적인 오류의 유형을 확인하는 것입니다.

Microsoft Entra ID

Microsoft Entra ID는 핵심 디렉터리 서비스, 고급 ID 거버넌스, 보안 및 애플리케이션 액세스 관리를 결합하는 포괄적인 ID 및 액세스 관리 클라우드 솔루션입니다. 또한 Microsoft Entra ID는 개발자에게 중앙 집중식 정책 및 규칙에 따라 애플리케이션에 액세스 제어를 제공하는 ID 관리 플랫폼을 제공합니다.

참고 항목

관리 서비스 ID 엔드포인트에 대한 다시 시도 지침은 토큰 획득을 위해 Azure VM MSI(관리 서비스 ID)를 사용하는 방법을 참조합니다.

재시도 메커니즘

MSAL(Microsoft 인증 라이브러리)에는 Microsoft Entra ID에 대한 기본 제공 재시도 메커니즘이 있습니다. 예기치 않은 잠금을 방지하려면 타사 라이브러리 및 애플리케이션 코드가 실패한 연결을 다시 시도하지 않도록 하지만 MSAL이 다시 시도를 처리하도록 허용하는 것이 좋습니다.

재시도 사용 지침

Microsoft Entra ID를 사용하는 경우 다음 지침을 고려합니다.

  • 가능한 경우 MSAL 라이브러리와 다시 시도에 대한 기본 제공 지원을 사용합니다.
  • Microsoft Entra ID용 REST API를 사용하는 경우 결과 코드가 429(너무 많은 요청) 또는 5xx 범위의 오류인 경우 작업을 다시 시도합니다. 다른 오류의 경우에는 재시도하지 마세요.
  • 429 오류의 경우 Retry-After 헤더에 표시된 시간 이후에만 다시 시도합니다.
  • 5xx 오류의 경우 응답 후 최소 5초 후에 첫 번째 다시 시도와 함께 지수 백오프를 사용합니다.
  • 429 및 5xx 이외의 오류에는 재시도하지 마세요.

다음 단계

Azure Cosmos DB

Azure Cosmos DB는 스키마 없는 JSON 데이터를 지원하는 완전 관리형 다중 모델 데이터베이스입니다. DocumentDB는 구성 가능하고 안정적인 성능, 네이티브 JavaScript 트랜잭션 처리를 제공하며 탄력적인 확장성으로 클라우드에 대해 구축됩니다.

재시도 메커니즘

Azure Cosmos DB SDK는 특정 오류 조건에서 자동으로 재시도하며 사용자 애플리케이션에는 자체 재시도 정책이 있는 것이 좋습니다. 오류 조건의 전체 목록과 재시도 시기는 Azure Cosmos DB SDK를 사용하여 복원력 있는 애플리케이션을 디자인하는 가이드를 참조하세요.

원격 분석

애플리케이션의 언어에 따라 진단 및 원격 분석은 작업 응답에서 로그 또는 승격된 속성으로 노출됩니다. 자세한 내용은 Azure Cosmos DB C# SDKAzure Cosmos DB Java SDK의 ‘진단 캡처’ 섹션을 참조하세요.

Data Lake Store

Data Lake Storage Gen2 는 Azure Storage를 Azure에서 엔터프라이즈 데이터 레이크를 빌드하기 위한 토대가 됩니다. Data Lake Storage Gen2를 사용하면 대량의 데이터를 쉽게 관리할 수 있습니다.

Azure Storage Files Data Lake 클라이언트 라이브러리에는 개발자, 데이터 과학자 및 분석가가 모든 크기, 모양 및 속도의 데이터를 쉽게 저장하고 플랫폼 및 언어에서 모든 유형의 처리 및 분석을 수행할 수 있도록 하는 데 필요한 모든 기능이 포함되어 있습니다.

재시도 메커니즘

DataLakeServiceClient를 사용하면 Azure Data Lake 서비스 리소스 및 파일 시스템을 조작할 수 있습니다. 스토리지 계정은 Data Lake 서비스에 대한 최상위 네임스페이스를 제공합니다. 클라이언트를 만들 때 Azure Data Lake 서비스(DataLakeClientOptions)에 연결하기 위한 클라이언트 구성 옵션을 제공할 수 있습니다. DataLakeClientOptions에는 구성할 수 있는 RetryOptions 속성(Azure.Core.ClientOptions에서 상속됨)이 포함되어 있습니다(RetryOptions 클래스).

원격

Azure Storage의 사용 및 성능을 모니터링하는 것은 서비스 운영의 중요한 부분입니다. 빈번한 작업, 대기 시간이 높은 작업 또는 서비스 쪽 제한을 유발하는 작업을 예로 들 수 있습니다.

스토리지 계정에 대한 모든 원격 분석은 Azure Monitor의 Azure Storage 로그를 통해 사용할 수 있습니다. 이 기능을 통해 스토리지 계정을 Log Analytics 및 Event Hubs와 통합할 수 있을 뿐 아니라 로그를 다른 스토리지 계정에 보관할 수 있습니다. 메트릭 및 리소스 로그의 전체 목록과 관련 스키마를 보려면 Azure Storage 모니터링 데이터 참조를 검토하세요.

Event Hubs

Azure Event Hubs는 수백만 개의 이벤트를 수집, 변환 및 저장하는 하이퍼스케일(hyper-scale) 원격 분석 수집 서비스입니다.

재시도 메커니즘

Azure Event Hubs 클라이언트 라이브러리의 재시도 동작은 EventHubClient 클래스의 RetryPolicy 속성에서 제어됩니다. 기본 정책에서는 Azure Event Hub가 일시적 EventHubsException 또는 OperationCanceledException를 반환할 때 지수 백오프를 통해 재시도합니다. Event Hubs에 대한 기본 재시도 정책은 최대 30초의 지수 백오프 시간으로 최대 9회 재시도하는 것입니다.

예제

EventHubClient client = EventHubClient.CreateFromConnectionString("[event_hub_connection_string]");
client.RetryPolicy = RetryPolicy.Default;

다음 단계

.NET용 Azure Event Hubs 클라이언트 라이브러리

IoT Hub

Azure IoT Hub는 IoT(사물 인터넷) 애플리케이션을 개발하기 위해 디바이스를 연결, 모니터링 및 관리하는 서비스입니다.

재시도 메커니즘

Azure IoT 디바이스 SDK는 네트워크, 프로토콜 또는 애플리케이션에서 오류를 검색할 수 있습니다. 오류 형식에 따라 SDK는 다시 시도를 수행해야 하는지 여부를 확인합니다. 오류가 복구 가능한 경우, SDK는 구성된 재시도 정책을 사용하여 다시 시도를 시작합니다.

기본 재시도 정책은 임의 지터를 사용한 지수적 백오프이지만 구성할 수 있습니다.

정책 구성

정책 구성은 언어에 따라 다릅니다. 자세한 내용은 IoT Hub 재시도 정책 구성을 참조하세요.

다음 단계

Azure Cache for Redis

Azure Cache for Redis는 자주 사용되는 오픈 소스 Redis Cache를 기반으로 하는 빠른 데이터 액세스 및 짧은 대기 시간 캐시 서비스입니다. 이는 안전하고 Microsoft에 의해 관리되며 Azure의 모든 애플리케이션에서 액세스할 수 있습니다.

이 섹션의 지침은 StackExchange.Redis 클라이언트를 사용하여 캐시에 액세스하는 지침을 기반으로 합니다. 기타 적합한 클라이언트 목록은 Redis 웹 사이트에서 확인할 수 있으며 클라이언트마다 재시도 메커니즘이 다를 수 있습니다.

StackExchange.Redis 클라이언트는 단일 연결을 통해 멀티플렉싱을 사용합니다. 권장되는 사용법은 애플리케이션 시작 시 클라이언트의 인스턴스를 만들고 캐시에 대한 모든 작업에 이 인스턴스를 사용하는 것입니다. 따라서 캐시에 한 번만 연결되므로 이 섹션의 모든 지침은 캐시에 액세스하는 각 작업이 아니라 이 초기 연결에 대한 재시도 정책과 관련이 있습니다.

재시도 메커니즘

StackExchange.Redis 클라이언트는 다음과 같이 옵션 집합을 통해 구성되는 연결 관리자 클래스를 사용합니다.

  • ConnectRetry. 실패한 캐시 연결을 재시도한 횟수입니다.
  • ReconnectRetryPolicy. 사용하는 재시도 전략입니다.
  • ConnectTimeout. 최대 대기 시간(밀리초)입니다.

정책 구성

재시도 정책은 캐시에 연결하기 전에 클라이언트에 대한 옵션을 설정하여 프로그래밍 방식으로 구성됩니다. 이 작업은 ConfigurationOptions 클래스의 인스턴스를 만들고 해당 속성을 채운 후 Connect 메서드에 전달하여 수행할 수 있습니다.

기본 제공 클래스는 임의 재시도 간격을 통해 선형(일정) 지연 및 지수 백오프를 지원합니다. IReconnectRetryPolicy 인터페이스를 구현하여 사용자 지정 재시도 정책을 만들 수도 있습니다.

다음 예제에서는 지수 백오프를 사용하여 재시도 전략을 구성합니다.

var deltaBackOffInMilliseconds = TimeSpan.FromSeconds(5).TotalMilliseconds;
var maxDeltaBackOffInMilliseconds = TimeSpan.FromSeconds(20).TotalMilliseconds;
var options = new ConfigurationOptions
{
    EndPoints = {"localhost"},
    ConnectRetry = 3,
    ReconnectRetryPolicy = new ExponentialRetry(deltaBackOffInMilliseconds, maxDeltaBackOffInMilliseconds),
    ConnectTimeout = 2000
};
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);

또는 옵션을 문자열로 지정하고 이를 Connect 메서드에 전달할 수 있습니다. ReconnectRetryPolicy 속성은 이 방식으로 설정할 수 없으며 코드로만 설정할 수 있습니다.

var options = "localhost,connectRetry=3,connectTimeout=2000";
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);

캐시에 연결할 때 직접 옵션을 지정할 수도 있습니다.

var conn = ConnectionMultiplexer.Connect("redis0:6380,redis1:6380,connectRetry=3");

자세한 내용은 StackExchange.Redis 설명서의 Stack Exchange Redis 구성을 참조하세요.

다음 표에서는 기본 제공 재시도 정책의 기본 설정을 보여 줍니다.

컨텍스트 설정 기본값
(v 1.2.2)
의미
ConfigurationOptions ConnectRetry

ConnectTimeout

SyncTimeout

ReconnectRetryPolicy
3

최대 5000ms와 SyncTimeout
1000

LinearRetry 5000ms
초기 연결 작업 중 연결 시도 반복 횟수입니다.
연결 작업에 대한 제한 시간(ms)입니다. 재시도 사이에 지연은 없습니다.
동기 작업을 허용하는 시간(ms)입니다.

5000 밀리초마다 다시 시도합니다.

참고

동기 작업의 경우 SyncTimeout을 엔드투엔드 대기 시간에 추가할 수 있으나 이 값을 너무 낮게 설정하면 과도한 시간 제한이 발생할 수 있습니다. Azure Cache for Redis 문제를 해결하는 방법을 참조하세요. 일반적으로 동기 작업보다는 비동기 작업을 사용합니다. 자세한 내용은 파이프라인 및 멀티플렉서(영문)를 참조하세요.

재시도 사용 지침

Azure Cache for Redis를 사용할 때 다음 지침을 고려합니다.

  • StackExchange Redis 클라이언트는 고유한 재시도를 관리하지만 애플리케이션이 처음 시작될 때 캐시에 대한 연결을 설정할 때만 관리합니다. 연결 제한 시간, 재시도 횟수 및 재시도 사이의 시간을 구성하여 이 연결을 설정할 수 있지만 재시도 정책은 캐시에 대한 작업에 적용되지 않습니다.
  • 많은 수의 재시도 횟수를 사용하는 대신 원래 데이터 소스에 액세스하여 폴백하는 것이 좋습니다.

원격 분석

TextWriter를 사용하여 다른 작업이 아닌 연결에 대한 정보를 수집할 수 있습니다.

var writer = new StringWriter();
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);

생성되는 출력의 예는 다음과 같습니다.

localhost:6379,connectTimeout=2000,connectRetry=3
1 unique nodes specified
Requesting tie-break from localhost:6379 > __Booksleeve_TieBreak...
Allowing endpoints 00:00:02 to respond...
localhost:6379 faulted: SocketFailure on PING
localhost:6379 failed to nominate (Faulted)
> UnableToResolvePhysicalConnection on GET
No masters detected
localhost:6379: Standalone v2.0.0, master; keep-alive: 00:01:00; int: Connecting; sub: Connecting; not in use: DidNotRespond
localhost:6379: int ops=0, qu=0, qs=0, qc=1, wr=0, sync=1, socks=2; sub ops=0, qu=0, qs=0, qc=0, wr=0, socks=2
Circular op-count snapshot; int: 0 (0.00 ops/s; spans 10s); sub: 0 (0.00 ops/s; spans 10s)
Sync timeouts: 0; fire and forget: 0; last heartbeat: -1s ago
resetting failing connections to retry...
retrying; attempts left: 2...
...

예제

다음 코드 예제에서는 StackExchange.Redis 클라이언트를 초기화할 때 재시도 사이에 일정(선형) 지연을 구성합니다. 이 예제에서는 ConfigurationOptions 인스턴스를 사용하여 구성을 설정하는 방법을 보여 줍니다.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StackExchange.Redis;

namespace RetryCodeSamples
{
    class CacheRedisCodeSamples
    {
        public async static Task Samples()
        {
            var writer = new StringWriter();
            {
                try
                {
                    var retryTimeInMilliseconds = TimeSpan.FromSeconds(4).TotalMilliseconds; // delay between retries

                    // Using object-based configuration.
                    var options = new ConfigurationOptions
                                        {
                                            EndPoints = { "localhost" },
                                            ConnectRetry = 3,
                                            ReconnectRetryPolicy = new LinearRetry(retryTimeInMilliseconds)
                                        };
                    ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);

                    // Store a reference to the multiplexer for use in the application.
                }
                catch
                {
                    Console.WriteLine(writer.ToString());
                    throw;
                }
            }
        }
    }
}

다음 예제에서는 옵션을 문자열로 지정하여 구성을 설정합니다. 연결 제한 시간은 재시도 간의 지연이 아니라 캐시에 대한 연결을 대기하는 최대 시간입니다. ReconnectRetryPolicy 속성은 코드로만 설정할 수 있습니다.

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StackExchange.Redis;

namespace RetryCodeSamples
{
    class CacheRedisCodeSamples
    {
        public async static Task Samples()
        {
            var writer = new StringWriter();
            {
                try
                {
                    // Using string-based configuration.
                    var options = "localhost,connectRetry=3,connectTimeout=2000";
                    ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);

                    // Store a reference to the multiplexer for use in the application.
                }
                catch
                {
                    Console.WriteLine(writer.ToString());
                    throw;
                }
            }
        }
    }
}

더 많은 예제는 프로젝트 웹 사이트의 구성(영문)을 참조하세요.

다음 단계

Azure Search를 사용하면 강력하고 정교한 검색 기능을 웹 사이트 또는 애플리케이션에 추가하고, 검색 결과를 쉽고 빠르게 조정하며, 풍부하고 미세 조정된 순위 모델을 생성할 수 있습니다.

재시도 메커니즘

.NET용 Azure SDK에는 이전 클라이언트 라이브러리인 Microsoft.Azure.Search와 기능적으로 동일한 Azure SDK 팀의 Azure.Search.Documents 클라이언트 라이브러리가 포함되어 있습니다.

Microsoft.Azure.Search재시도 동작은 SearchServiceClient 및 SearchIndexClient 클래스의 SetRetryPolicy 메서드에 의해 제어됩니다. Azure Search가 5xx 또는 408(요청 시간 초과) 응답을 반환하는 경우 기본 정책은 지수 백오프를 다시 시도합니다.

Azure.Search.Documents의 재시도 동작은 Azure.Core.RetryOptions(모든 구성을 사용할 수 있는 경우) 클래스에 속하는 속성 Retry의 SearchClientOptions(SearchClient 생성자의 일부임)에 의해 제어됩니다.

원격 분석

ETW를 사용하거나 사용자 지정 추적 공급자를 등록하는 추적입니다. 자세한 내용은 AutoRest 설명서를 참조하세요.

Service Bus

Service Bus는 클라우드에서 호스트되는지 온-프레미스에서 호스트되는지에 관계없이 향상된 확장성 및 복원력으로 느슨하게 결합된 메시지 교환을 애플리케이션의 구성 요소에 제공하는 클라우드 메시징 플랫폼입니다.

재시도 메커니즘

네임스페이스 및 일부 구성 세부 정보는 사용되는 Service Bus 클라이언트 SDK 패키지에 따라 다릅니다.

패키지 Description 네임스페이스
Azure.Messaging.ServiceBus .NET용 Azure Service Bus 클라이언트 라이브러리 Azure.Messaging.ServiceBus
WindowsAzure.ServiceBus 이 패키지는 이전 Service Bus 클라이언트 라이브러리입니다. .NET Framework 4.5.2가 필요합니다. Microsoft.Azure.ServiceBus

재시도 사용 지침

ServiceBusRetryOptions 속성은 ServiceBusClient 개체를 위한 재시도 옵션을 지정합니다.

설정 기본값 의미
CustomRetryPolicy 개별 옵션 값 대신 사용할 사용자 지정 재시도 정책입니다.
Delay 0.8초 고정된 접근 방식을 위한 재시도 사이의 지연 시간 또는 백오프 기반 접근 방식을 위한 베이스 계산에 의한 지연 시간입니다.
MaxDelay 60초 재시도 사이에 허용되는 최대 지연 시간입니다.
MaxRetries 3 연결된 작업이 실패한 것으로 간주하기 전 최대 다시 시도 횟수입니다.
모드 지수 다시 시도 지연을 계산하는 데 사용하는 방법입니다.
TryTimeout 60초 초기 시도 또는 재시도 여부에 관계없이 단일 시도가 완료될 때까지 대기하는 최대 기간입니다.

다음 값으로 ServiceBusRetryMode를 구성하도록 Mode 속성을 설정합니다.

속성 설명
지수 1 재시도하면 시도할 때마다 재시도 전에 대기하는 기간을 증가시키는 백오프 전략에 기반해 지연 시간이 발생합니다.
고정 0 재시도는 고정된 간격으로 발생합니다. 각 지연 시간의 길이는 일정합니다.

예제:

using Azure.Messaging.ServiceBus;

string connectionString = "<connection_string>";
string queueName = "<queue_name>";

// Because ServiceBusClient implements IAsyncDisposable, we'll create it
// with "await using" so that it is automatically disposed for us.
var options = new ServiceBusClientOptions();
options.RetryOptions = new ServiceBusRetryOptions
{
    Delay = TimeSpan.FromSeconds(10),
    MaxDelay = TimeSpan.FromSeconds(30),
    Mode = ServiceBusRetryMode.Exponential,
    MaxRetries = 3,
};
await using var client = new ServiceBusClient(connectionString, options);

원격 분석

Service Bus는 다른 Azure 리소스와 동일한 종류의 모니터링 데이터를 수집합니다. Azure Monitor를 사용하여 Azure Service Bus를 모니터링할 수 있습니다.

Service Bus .NET 클라이언트 라이브러리를 사용하여 원격 분석을 전송하기 위한 다양한 옵션도 제공됩니다.

예제

다음 코드 예제는 Azure.Messaging.ServiceBus 패키지를 사용하는 방법을 보여 줍니다.

  • ServiceBusClientOptions를 사용하여 ServiceBusClient에 대한 재시도 정책을 설정합니다.
  • ServiceBusMessage의 새 인스턴스를 사용하여 새 메시지를 만듭니다.
  • ServiceBusSender.SendMessageAsync(message) 메서드를 사용하여 Service Bus에 메시지를 보냅니다.
  • ServiceBusReceivedMessage 개체로 표시되는 ServiceBusReceiver를 사용하여 수신합니다.
// using Azure.Messaging.ServiceBus;

using Azure.Messaging.ServiceBus;

string connectionString = "<connection_string>";
string queueName = "queue1";

// Because ServiceBusClient implements IAsyncDisposable, we'll create it 
// with "await using" so that it is automatically disposed for us.
var options = new ServiceBusClientOptions();
options.RetryOptions = new ServiceBusRetryOptions
{
    Delay = TimeSpan.FromSeconds(10),
    MaxDelay = TimeSpan.FromSeconds(30),
    Mode = ServiceBusRetryMode.Exponential,
    MaxRetries = 3,
};
await using var client = new ServiceBusClient(connectionString, options);

// The sender is responsible for publishing messages to the queue.
ServiceBusSender sender = client.CreateSender(queueName);
ServiceBusMessage message = new ServiceBusMessage("Hello world!");

await sender.SendMessageAsync(message);

// The receiver is responsible for reading messages from the queue.
ServiceBusReceiver receiver = client.CreateReceiver(queueName);
ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();

string body = receivedMessage.Body.ToString();
Console.WriteLine(body);

다음 단계

Service Fabric

Service Fabric 클러스터에서 신뢰할 수 있는 서비스를 배포하면 이 문서에서 논의된 대부분의 가능한 일시적 오류를 방지할 수 있습니다. 그러나 일부 일시적 오류는 발생할 수 있습니다. 예를 들어 명명 서비스가 변경을 전달하는 도중에 요청을 받으면 예외가 발생할 수 있습니다. 같은 요청을 100밀리초 후에 받으면 성공할 수 있습니다.

Service Fabric은 내부적으로 이런 종류의 일시적 오류를 관리합니다. 서비스를 설정할 때 OperationRetrySettings 클래스를 사용하여 일부 설정을 구성할 수 있습니다. 다음은 예를 보여 주는 코드입니다. 이것은 대부분의 경우 불필요하며 기본 설정으로 충분합니다.

FabricTransportRemotingSettings transportSettings = new FabricTransportRemotingSettings
{
    OperationTimeout = TimeSpan.FromSeconds(30)
};

var retrySettings = new OperationRetrySettings(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(1), 5);

var clientFactory = new FabricTransportServiceRemotingClientFactory(transportSettings);

var serviceProxyFactory = new ServiceProxyFactory((c) => clientFactory, retrySettings);

var client = serviceProxyFactory.CreateServiceProxy<ISomeService>(
    new Uri("fabric:/SomeApp/SomeStatefulReliableService"),
    new ServicePartitionKey(0));

다음 단계

ADO.NET을 사용하는 SQL Database

SQL Database는 다양한 크기와 표준(공유) 및 프리미엄(비공유) 서비스로 사용할 수 있는 호스트된 SQL Database입니다.

재시도 메커니즘

SQL Database는 ADO.NET을 사용하여 액세스하는 경우 재시도에 대한 기본 제공 지원을 제공하지 않습니다. 그러나 요청에서 반환된 코드를 사용하여 요청이 실패한 이유를 확인할 수 있습니다. SQL Database 제한에 대한 자세한 내용은 Azure SQL Database 리소스 제한을 참조하세요. 관련 오류 코드 목록은 SQL Database 클라이언트 애플리케이션에 대한 SQL 오류 코드를 참조하세요.

SQL Database에 대한 재시도 구현에 Polly 라이브러리를 사용할 수 있습니다. Polly를 통한 일시적인 오류 처리를 참조하세요.

재시도 사용 지침

ADO.NET을 사용하는 SQL Database에 액세스하는 경우 다음 지침을 고려합니다.

  • 적절한 서비스 옵션(공유 또는 프리미엄)을 선택합니다. 공유 인스턴스는 공유 서버의 다른 테넌트에서 사용되기 때문에 일반적인 연결 지연 및 제한보다 더 길게 영향을 받을 수 있습니다. 예측 가능한 성능 및 대기 시간이 짧은 안정적인 작업이 필요한 경우 프리미엄 옵션을 선택하는 것이 좋습니다.
  • 적절한 수준 또는 범위에서 재시도를 수행하여 데이터 불일치를 발생시키는 비멱등 작업을 방지해야 합니다. 이상적으로는 불일치를 발생시키지 않고 반복할 수 있도록 모든 작업이 멱등이어야 합니다. 그렇지 않은 경우 한 작업이 실패하면 모든 관련 변경 내용이 실행 취소되도록 하는 수준 또는 범위(예: 트랜잭션 범위 내)에서 재시도를 수행해야 합니다. 자세한 내용은 클라우드 서비스의 기본 데이터 액세스 계층 – 일시적인 오류 처리(영문)를 참조하세요.
  • 고정 간격 전략은 짧은 간격에 몇 번의 재시도만 수행되는 대화형 시나리오를 제외하고 Azure SQL Database에서 사용하지 않는 것이 좋습니다. 대신 대부분의 시나리오에 지수 백오프 전략을 사용하는 것이 좋습니다.
  • 연결을 정의할 때 연결 및 명령 제한 시간에 적합한 값을 선택합니다. 제한 시간이 너무 짧으면 데이터베이스가 사용 중일 때 중간에 연결 오류가 발생할 수 있습니다. 제한 시간이 너무 길면 실패한 연결을 검색할 때까지 너무 오래 대기하여 재시도 논리가 올바르게 작동하지 못할 수 있습니다. 제한 시간 값은 엔드투엔드 대기 시간의 구성 요소이므로 모든 재시도에 대한 재시도 정책에 지정된 재시도 지연 시간에 효과적으로 추가됩니다.
  • 지수 백오프 재시도 논리를 사용하는 경우에도 몇 번의 재시도 후에는 연결을 닫고 새 연결에서 작업을 재시도합니다. 동일한 연결에서 동일한 작업을 여러 번 재시도하면 연결 문제에 영향을 주는 요인이 될 수 있습니다. 이 기술에 대한 예제는 클라우드 서비스의 기본 데이터 액세스 계층 – 일시적인 오류 처리(영문)를 참조하세요.
  • 연결 풀링이 사용 중(기본값)인 경우 연결을 닫았다가 다시 연 후에도 풀에서 동일한 연결을 선택할 수 있습니다. 이런 경우 해결 방법은 SqlConnection 클래스의 ClearPool 메서드를 호출하여 연결을 재사용할 수 없음으로 표시하는 것입니다. 그러나 이 방법은 여러 번의 연결 시도가 실패한 후에만 수행하고 오류가 발생한 연결과 관련된 SQL 제한 시간(오류 코드 -2)과 같은 특정 클래스의 일시적인 오류가 발생하는 경우에만 수행해야 합니다.
  • 데이터 액세스 코드가 TransactionScope 인스턴스로 시작된 트랜잭션을 사용하는 경우 재시도 논리에서 연결을 다시 열고 새 트랜잭션 범위를 시작해야 합니다. 이러한 이유로 재시도 가능한 코드 블록은 트랜잭션의 전체 범위를 포함해야 합니다.

재시도 작업에 대해 다음 설정을 사용하여 시작하는 것이 좋습니다. 이러한 설정은 범용이므로 작업을 모니터링하고 고유의 시나리오에 맞게 값을 미세 조정해야 합니다.

컨텍스트 샘플 대상 E2E
최대 대기 시간
재시도 전략 설정 작동 방법
대화형, UI
또는 포그라운드
2초 FixedInterval 재시도 횟수
재시도 간격
첫 번째 빠른 재시도
3
500ms
true
시도 1 - 0초 지연
시도 2 - 500ms 지연
시도 3 - 500ms 지연
배경
또는 일괄 처리
30초 ExponentialBackoff 재시도 횟수
최소 백오프
최대 백오프
델타 백오프
첫 번째 빠른 재시도
5
0초
60초
2초
false
시도 1 - 0초 지연
시도 2 - ~2초 지연
시도 3 - ~6초 지연
시도 4 - ~14초 지연
시도 5 - ~30초 지연

참고

엔드투엔드 대기 시간 대상은 서비스에 대한 연결의 기본 제한 시간을 가정합니다. 연결 제한 시간을 더 길게 지정하면 엔드투엔드 대기 시간이 모든 재시도에 대해 이 추가 시간만큼 확장됩니다.

예제

이 섹션에서는 Policy 클래스에 구성된 재시도 정책 세트를 사용하는 Azure SQL Database에 Polly를 사용하여 액세스하는 방법을 보여 줍니다.

다음 코드는 지수 백오프를 통해 ExecuteAsync를 호출하는 SqlCommand 클래스의 확장 메서드를 보여 줍니다.

public async static Task<SqlDataReader> ExecuteReaderWithRetryAsync(this SqlCommand command)
{
    GuardConnectionIsNotNull(command);

    var policy = Policy.Handle<Exception>().WaitAndRetryAsync(
        retryCount: 3, // Retry 3 times
        sleepDurationProvider: attempt => TimeSpan.FromMilliseconds(200 * Math.Pow(2, attempt - 1)), // Exponential backoff based on an initial 200 ms delay.
        onRetry: (exception, attempt) =>
        {
            // Capture some information for logging/telemetry.
            logger.LogWarn($"ExecuteReaderWithRetryAsync: Retry {attempt} due to {exception}.");
        });

    // Retry the following call according to the policy.
    await policy.ExecuteAsync<SqlDataReader>(async token =>
    {
        // This code is executed within the Policy

        if (conn.State != System.Data.ConnectionState.Open) await conn.OpenAsync(token);
        return await command.ExecuteReaderAsync(System.Data.CommandBehavior.Default, token);

    }, cancellationToken);
}

이 비동기 확장 메서드는 다음과 같이 사용할 수 있습니다.

var sqlCommand = sqlConnection.CreateCommand();
sqlCommand.CommandText = "[some query]";

using (var reader = await sqlCommand.ExecuteReaderWithRetryAsync())
{
    // Do something with the values
}

다음 단계

Entity Framework 6을 사용하는 SQL Database

SQL Database는 다양한 크기와 표준(공유) 및 프리미엄(비공유) 서비스로 사용할 수 있는 호스트된 SQL Database입니다. Entity Framework는 .NET 개발자가 도메인별 개체를 사용하여 관계형 데이터로 작업할 수 있는 개체 관계형 매퍼입니다. 여기서는 개발자가 일반적으로 작성해야 하는 대부분의 데이터 액세스 코드가 필요하지 않습니다.

재시도 메커니즘

재시도는 연결 복원/재시도 논리(영문)라는 메커니즘을 통해 Entity Framework 6.0 이상을 사용하는 SQL Database에 액세스할 때 지원됩니다. 재시도 메커니즘의 주요 기능은 다음과 같습니다.

  • 기본 추상화는 IDbExecutionStrategy 인터페이스입니다. 이 인터페이스:
    • 동기 및 비동기 Execute 메서드를 정의합니다.
    • 직접 사용하거나 데이터베이스 컨텍스트에서 기본 전략으로 구성하거나, 공급자 이름에 매핑하거나, 공급자 이름 및 서버 이름에 매핑할 수 있는 클래스를 정의합니다. 컨텍스트에서 구성할 경우 재시도는 지정된 컨텍스트 작업에 대해 여러 개가 있을 수 있는 개별 데이터베이스 작업 수준에서 수행됩니다.
    • 실패한 연결을 재시도할 시기 및 방법을 정의합니다.
  • 여기에는 IDbExecutionStrategy 인터페이스의 몇 가지 기본 제공 구현이 포함됩니다.
    • 기본값: 다시 시도하지 않음.
    • SQL Database(자동)에 대한 기본값: 다시 시도하지 않지만 예외를 검사하고 SQL Database 전략을 사용하는 제안으로 래핑합니다.
    • SQL Database에 대한 기본값: 지수(기본 클래스에서 상속됨) 및 SQL Database 검색 논리.
  • 불규칙을 포함하는 지수 백오프 전략을 구현합니다.
  • 기본 제공 재시도 클래스는 상태 저장 클래스이며 스레드로부터 안전하지 않습니다. 그러나 현재 작업이 완료된 후 다시 사용할 수 있습니다.
  • 지정된 재시도 횟수를 초과하는 경우 결과는 새 예외에 래핑됩니다. 현재 예외를 버블 업하지 않습니다.

정책 구성

재시도는 Entity Framework 6.0 이상을 사용하는 SQL Database에 액세스할 때 지원됩니다. 재시도 정책은 프로그래밍 방식으로 구성됩니다. 구성은 작업 단위로 변경할 수 없습니다.

컨텍스트에서 기본값으로 전략을 구성하는 경우 필요에 따라 새 전략을 만드는 함수를 지정합니다. 다음 코드에서는 DbConfiguration 기본 클래스를 확장하는 재시도 구성 클래스를 만드는 방법을 보여 줍니다.

public class BloggingContextConfiguration : DbConfiguration
{
  public BlogConfiguration()
  {
    // Set up the execution strategy for SQL Database (exponential) with 5 retries and 4 sec delay
    this.SetExecutionStrategy(
         "System.Data.SqlClient", () => new SqlAzureExecutionStrategy(5, TimeSpan.FromSeconds(4)));
  }
}

그런 다음 애플리케이션이 시작될 때 DbConfiguration 인스턴스의 SetConfiguration 메서드를 사용하여 모든 작업에 대해 기본 재시도 전략으로 지정할 수 있습니다. 기본적으로 EF는 구성 클래스를 자동으로 검색하고 사용합니다.

DbConfiguration.SetConfiguration(new BloggingContextConfiguration());

DbConfigurationType 특성으로 컨텍스트 클래스에 주석을 추가하여 컨텍스트에 대한 재시도 구성 클래스를 지정할 수 있습니다. 그러나 구성 클래스가 하나만 있는 경우 EF는 컨텍스트에 주석을 추가할 필요 없이 해당 클래스를 사용합니다.

[DbConfigurationType(typeof(BloggingContextConfiguration))]
public class BloggingContext : DbContext

특정 작업에 다른 재시도 전략을 사용하거나 특정 작업에 대해 재시도를 사용하지 않도록 설정해야 하는 경우 CallContext에서 플래그를 설정하여 전략을 일시 중단하거나 교환할 수 있도록 하는 구성 클래스를 만들 수 있습니다. 구성 클래스는 이 플래그를 사용하여 전략을 전환하거나, 제공된 전략을 사용하지 않도록 설정하고 기본 전략을 사용할 수 있습니다. 자세한 내용은 실행 전략 일시 중단(EF6 이상)을 참조하세요.

개별 작업에 특정 재시도 전략을 사용하기 위한 다른 기술은 필요한 전략 클래스의 인스턴스를 만들고 매개 변수를 통해 원하는 설정을 제공하는 것입니다. 그런 다음 ExecuteAsync 메서드를 호출합니다.

var executionStrategy = new SqlAzureExecutionStrategy(5, TimeSpan.FromSeconds(4));
var blogs = await executionStrategy.ExecuteAsync(
    async () =>
    {
        using (var db = new BloggingContext("Blogs"))
        {
            // Acquire some values asynchronously and return them
        }
    },
    new CancellationToken()
);

DbConfiguration 클래스를 사용하는 가장 간단한 방법은 DbContext 클래스와 동일한 어셈블리에 배치하는 것입니다. 그러나 다양한 대화형 및 백그라운드 재시도 전략과 같이 서로 다른 시나리오에서 동일한 컨텍스트가 필요한 경우에는 적합하지 않습니다. 서로 다른 컨텍스트가 별도의 AppDomain에서 실행되는 경우 구성 파일에서 구성 클래스를 지정하는 데 기본 제공 지원을 사용하거나 코드를 사용하여 명시적으로 설정할 수 있습니다. 다른 컨텍스트가 동일한 AppDomain에서 실행되어야 하는 경우 사용자 지정 솔루션이 필요합니다.

자세한 내용은 코드 기반 구성(EF6 이상)을 참조하세요.

다음 표에서는 EF6을 사용하는 경우 기본 제공 재시도 정책의 기본 설정을 보여 줍니다.

설정 기본값 의미
정책 지수 지수적 백오프.
MaxRetryCount 5 최대 재시도 수
MaxDelay 30초 재시도 사이의 최대 지연. 이 값은 일련의 지연 시간이 계산되는 방식에는 영향이 없습니다. 상한 값만 정의합니다.
DefaultCoefficient 1초 지수 백오프 계산을 위한 계수. 이 값은 변경할 수 없습니다.
DefaultRandomFactor 1.1 각 항목에 대해 임의 지연을 추가하는 데 사용되는 승수입니다. 이 값은 변경할 수 없습니다.
DefaultExponentialBase 2 다음 지연을 계산하는 데 사용되는 승수입니다. 이 값은 변경할 수 없습니다.

재시도 사용 지침

EF6을 사용하는 SQL Database에 액세스하는 경우 다음 지침을 고려합니다.

  • 적절한 서비스 옵션(공유 또는 프리미엄)을 선택합니다. 공유 인스턴스는 공유 서버의 다른 테넌트에서 사용되기 때문에 일반적인 연결 지연 및 제한보다 더 길게 영향을 받을 수 있습니다. 예측 가능한 성능 및 대기 시간이 짧은 안정적인 작업이 필요한 경우 프리미엄 옵션을 선택하는 것이 좋습니다.

  • Azure SQL Database에는 고정 간격 전략을 사용하지 않는 것이 좋습니다. 대신 서비스가 오버로드될 수 있고 더 긴 지연으로 인해 복구에 더 많은 시간이 필요할 수 있으므로 지수 백오프 전략을 사용합니다.

  • 연결을 정의할 때 연결 및 명령 제한 시간에 적합한 값을 선택합니다. 제한 시간은 비즈니스 논리 디자인 및 테스트를 기반으로 합니다. 시간에 따라 데이터의 양이나 비즈니스 프로세스가 변경되므로 이 값을 수정해야 할 수 있습니다. 제한 시간이 너무 짧으면 데이터베이스가 사용 중일 때 중간에 연결 오류가 발생할 수 있습니다. 제한 시간이 너무 길면 실패한 연결을 검색할 때까지 너무 오래 대기하여 재시도 논리가 올바르게 작동하지 못할 수 있습니다. 제한 시간 값은 엔드투엔드 대기 시간의 구성 요소이지만 컨텍스트를 저장할 때 실행될 명령 수를 쉽게 확인할 수 없습니다. DbContext 인스턴스의 CommandTimeout 속성을 설정하여 기본 제한 시간을 변경할 수 있습니다.

  • Entity Framework는 구성 파일에 정의된 재시도 구성을 지원합니다. 그러나 Azure에서 최대한의 유연성을 제공하려면 애플리케이션 내에서 프로그래밍 방식으로 구성을 만드는 것이 좋습니다. 재시도 정책에 대한 특정 매개 변수(예: 재시도 횟수 및 다시 시도 간격)는 서비스 구성 파일에 저장하여 런타임에 적절한 정책을 만드는 데 사용할 수 있습니다. 이렇게 하면 애플리케이션을 다시 시작하지 않고도 설정을 변경할 수 있습니다.

재시도 작업에 대해 다음 설정을 사용하여 시작하는 것이 좋습니다. 재시도 사이의 지연 시간을 지정할 수 없습니다. 이 값은 고정이며 지수 시퀀스로 생성됩니다. 다음과 같이 사용자 지정 재시도 전략을 만들지 않는 경우 최대값만 지정할 수 있습니다. 이러한 설정은 범용이므로 작업을 모니터링하고 고유의 시나리오에 맞게 값을 미세 조정해야 합니다.

컨텍스트 샘플 대상 E2E
최대 대기 시간
재시도 정책 설정 작동 방법
대화형, UI
또는 포그라운드
2초 지수 MaxRetryCount
MaxDelay
3
750ms
시도 1 - 0초 지연
시도 2 - 750ms 지연
시도 3 – 750ms 지연
배경
또는 일괄 처리
30초 지수 MaxRetryCount
MaxDelay
5
12초
시도 1 - 0초 지연
시도 2 - ~1초 지연
시도 3 - ~3초 지연
시도 4 - ~7초 지연
시도 5 - ~12초 지연

참고

엔드투엔드 대기 시간 대상은 서비스에 대한 연결의 기본 제한 시간을 가정합니다. 연결 제한 시간을 더 길게 지정하면 엔드투엔드 대기 시간이 모든 재시도에 대해 이 추가 시간만큼 확장됩니다.

예제

다음 코드 예제에서는 Entity Framework를 사용하는 간단한 데이터 액세스 솔루션을 정의합니다. 이 예제에서는 DbConfiguration을 확장하는 BlogConfiguration이라는 클래스의 인스턴스를 정의하여 특정 재시도 전략을 설정합니다.

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.SqlServer;
using System.Threading.Tasks;

namespace RetryCodeSamples
{
    public class BlogConfiguration : DbConfiguration
    {
        public BlogConfiguration()
        {
            // Set up the execution strategy for SQL Database (exponential) with 5 retries and 12 sec delay.
            // These values could be loaded from configuration rather than being hard-coded.
            this.SetExecutionStrategy(
                    "System.Data.SqlClient", () => new SqlAzureExecutionStrategy(5, TimeSpan.FromSeconds(12)));
        }
    }

    // Specify the configuration type if more than one has been defined.
    // [DbConfigurationType(typeof(BlogConfiguration))]
    public class BloggingContext : DbContext
    {
        // Definition of content goes here.
    }

    class EF6CodeSamples
    {
        public async static Task Samples()
        {
            // Execution strategy configured by DbConfiguration subclass, discovered automatically or
            // or explicitly indicated through configuration or with an attribute. Default is no retries.
            using (var db = new BloggingContext("Blogs"))
            {
                // Add, edit, delete blog items here, then:
                await db.SaveChangesAsync();
            }
        }
    }
}

Entity Framework 다시 시도 메커니즘 사용에 대한 더 많은 예제는 연결 복구/다시 시도 논리(영문)에서 확인할 수 있습니다.

Entity Framework Core를 사용하는 SQL Database

Entity Framework Core는 .NET Core 개발자가 도메인별 개체를 사용하여 데이터로 작업할 수 있는 개체 관계형 매퍼입니다. 여기서는 개발자가 일반적으로 작성해야 하는 대부분의 데이터 액세스 코드가 필요하지 않습니다. 이 Entity Framework 버전은 처음부터 새로 작성되었으며 EF6.x의 모든 기능을 자동으로 상속하지는 않습니다.

재시도 메커니즘

재시도 지원은 연결 복원력이라는 메커니즘을 통해 Entity Framework Core를 사용하는 SQL Database에 액세스할 때 제공됩니다. 연결 복원력은 EF Core 1.1.0에서 도입되었습니다.

기본 추상화는 IExecutionStrategy 인터페이스입니다. SQL Azure를 포함한 SQL Server 실행 전략은 항상 재시도할 수 있는 예외 유형을 인지하며 최대 재시도, 재시도 간 지연 등에 대한 인식 가능한 기본값을 갖습니다.

예제

다음 코드는 데이터베이스와의 세션을 나타내는 DbContext 개체를 구성할 때 자동 재시도를 구현합니다.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer(
            @"Server=(localdb)\mssqllocaldb;Database=EFMiscellaneous.ConnectionResiliency;Trusted_Connection=True;",
            options => options.EnableRetryOnFailure());
}

다음 코드는 실행 전략을 사용하여 자동 재시도가 있는 트랜잭션 실행 방법을 나타냅니다. 트랜잭션은 대리자에서 정의됩니다. 일시적인 오류가 발생하면, 실행 전략에서 대리자를 다시 호출합니다.

using (var db = new BloggingContext())
{
    var strategy = db.Database.CreateExecutionStrategy();

    strategy.Execute(() =>
    {
        using (var transaction = db.Database.BeginTransaction())
        {
            db.Blogs.Add(new Blog { Url = "https://blogs.msdn.com/dotnet" });
            db.SaveChanges();

            db.Blogs.Add(new Blog { Url = "https://blogs.msdn.com/visualstudio" });
            db.SaveChanges();

            transaction.Commit();
        }
    });
}

Azure Storage

Azure Storage 서비스에는 Blob Storage, 파일 및 스토리지 큐가 포함됩니다.

Blob, 큐 및 파일

ClientOptions 클래스는 모든 클라이언트 옵션 유형의 기본 형식이며 진단, 다시 시도, 전송과 같은 다양한 공통 클라이언트 옵션을 제공합니다. Azure Queue, Blob 및 File Storage에 연결하기 위한 클라이언트 구성 옵션을 제공하려면 해당 파생 유형을 사용해야 합니다. 다음 예에서는 QueueClientOptions 클래스(ClientOptions에서 파생됨)를 사용하여 Azure Queue Service에 연결하도록 클라이언트를 구성합니다. Retry 속성은 다시 시도 방법과 실패를 다시 시도할 수 있는 방법에 영향을 주기 위해 지정할 수 있는 옵션 집합입니다.

using System;
using System.Threading;
using Azure.Core;
using Azure.Identity;
using Azure.Storage;
using Azure.Storage.Queues;
using Azure.Storage.Queues.Models;

namespace RetryCodeSamples
{
    class AzureStorageCodeSamples {

        public async static Task Samples() {

               // Provide the client configuration options for connecting to Azure Queue Storage
                QueueClientOptions queueClientOptions = new QueueClientOptions()
                {
                    Retry = {
                    Delay = TimeSpan.FromSeconds(2),     //The delay between retry attempts for a fixed approach or the delay on which to base
                                                         //calculations for a backoff-based approach
                    MaxRetries = 5,                      //The maximum number of retry attempts before giving up
                    Mode = RetryMode.Exponential,        //The approach to use for calculating retry delays
                    MaxDelay = TimeSpan.FromSeconds(10)  //The maximum permissible delay between retry attempts
                    },

                    GeoRedundantSecondaryUri = new Uri("https://...")
                    // If the GeoRedundantSecondaryUri property is set, the secondary Uri will be used for GET or HEAD requests during retries.
                    // If the status of the response from the secondary Uri is a 404, then subsequent retries for the request will not use the
                    // secondary Uri again, as this indicates that the resource may not have propagated there yet.
                    // Otherwise, subsequent retries will alternate back and forth between primary and secondary Uri.
                };

                Uri queueServiceUri = new Uri("https://storageaccount.queue.core.windows.net/");
                string accountName = "Storage account name";
                string accountKey = "storage account key";

                // Create a client object for the Queue service, including QueueClientOptions.
                QueueServiceClient serviceClient = new QueueServiceClient(queueServiceUri, new DefaultAzureCredential(), queueClientOptions);

                CancellationTokenSource source = new CancellationTokenSource();
                CancellationToken cancellationToken = source.Token;

                // Return an async collection of queues in the storage account.
                var queues = serviceClient.GetQueuesAsync(QueueTraits.None, null, cancellationToken);

테이블 지원

참고 항목

WindowsAzure.Storage Nuget 패키지 및 Microsoft.Azure.Cosmos.Table Nuget 패키지는 더 이상 사용되지 않습니다. Azure 테이블 지원은 Azure.Data.Tables Nuget 패키지를 참조 하세요.

재시도 메커니즘

클라이언트 라이브러리는 다른 클라이언트 라이브러리에 교차 절단 서비스를 제공하는 라이브러리인 Azure Core 라이브러리를 기반으로 합니다.

클라이언트 애플리케이션이 서비스에 네트워크 요청을 보내려고 할 때 오류가 발생할 수 있는 여러 가지 이유가 있습니다. 몇 가지 예로는 제한 시간, 네트워크 인프라 오류, 제한/사용 중으로 인해 요청을 거부하는 서비스, 서비스 규모 축소로 인한 서비스 인스턴스 종료, 서비스 인스턴스가 다른 버전으로 교체됨, 처리되지 않은 예외로 인한 서비스 크래시 등이 있습니다. 기본 제공 재시도 메커니즘(소비자가 재정의할 수 있는 기본 구성)을 제공하면 SDK 및 소비자의 애플리케이션이 이러한 종류의 오류에 탄력적이 됩니다. 일부 서비스는 각 요청에 대해 실제 비용을 청구하므로 소비자는 복원력보다 비용을 절감하려는 경우 재시도를 완전히 사용하지 않도록 설정할 수 있어야 합니다.

정책 구성

재시도 정책은 프로그래밍 방식으로 구성됩니다. 구성은 RetryOption 클래스기반으로 합니다. ClientOptions에서 상속된 TableClientOptions특성이 있습니다.

      var tableClientOptions = new TableClientOptions();
      tableClientOptions.Retry.Mode = RetryMode.Exponential;
      tableClientOptions.Retry.MaxRetries = 5;
      var serviceClient = new TableServiceClient(connectionString, tableClientOptions);

다음 표에서는 기본 제공 재시도 정책에 대한 가능성을 보여 줍니다.

RetryOption

설정 의미
Delay 고정된 접근 방식을 위한 재시도 사이의 지연 시간 또는 백오프 기반 접근 방식을 위한 베이스 계산에 의한 지연 시간입니다. 서비스에서 Retry-After 응답 헤더를 제공하는 경우 헤더 값으로 지정된 기간으로 인해 다음 재시도가 지연됩니다.
MaxDelay 서비스에서 Retry-After 응답 헤더를 제공하지 않는 경우 재시도 시도 사이의 최대 허용 지연 시간입니다. 서비스에서 Retry-After 응답 헤더를 제공하는 경우 헤더 값으로 지정된 기간으로 인해 다음 재시도가 지연됩니다.
모드 다시 시도 지연을 계산하는 데 사용하는 방법입니다.
NetworkTimeout 개별 네트워크 작업에 적용되는 시간 제한입니다.

RetryMode

설정 의미
지수 재시도하면 시도할 때마다 재시도 전에 대기하는 기간을 증가시키는 백오프 전략에 기반해 지연 시간이 발생합니다.
MaxDelay 재시도는 고정된 간격으로 발생합니다. 각 지연 시간의 길이는 일정합니다.

원격

로그를 확인하는 가장 간단한 방법은 콘솔 로깅을 사용하도록 설정하는 것입니다. 콘솔에 메시지를 출력하는 Azure SDK 로그 수신기를 만들려면 AzureEventSourceListener.CreateConsoleLogger 메서드를 사용합니다.

      // Setup a listener to monitor logged events.
      using AzureEventSourceListener listener = AzureEventSourceListener.CreateConsoleLogger();

예제

스토리지 에뮬레이터를 종료하여 다음 코드 예제를 실행하면 콘솔에서 재시도에 대한 정보를 볼 수 있습니다.

using Azure.Core;
using Azure.Core.Diagnostics;
using Azure.Data.Tables;
using Azure.Data.Tables.Models;

namespace RetryCodeSamples
{
    class AzureStorageCodeSamples
    {
        private const string connectionString = "UseDevelopmentStorage=true";
        private const string tableName = "RetryTestTable";

        public async static Task SamplesAsync()
        {
            // Setup a listener to monitor logged events.
            using AzureEventSourceListener listener = AzureEventSourceListener.CreateConsoleLogger();

            var tableClientOptions = new TableClientOptions();
            tableClientOptions.Retry.Mode = RetryMode.Exponential;
            tableClientOptions.Retry.MaxRetries = 5;

            var serviceClient = new TableServiceClient(connectionString, tableClientOptions);

            TableItem table = await serviceClient.CreateTableIfNotExistsAsync(tableName);
            Console.WriteLine($"The created table's name is {table.Name}.");
        }
    }
}

일반 REST 및 다시 시도 지침

Azure 또는 타사 서비스에 액세스하는 경우 다음 사항을 고려합니다.

  • 재사용 가능한 코드로 재시도를 관리하는 체계적인 방법을 사용하여 모든 클라이언트 및 모든 솔루션에서 일관된 방법론을 적용할 수 있도록 합니다.

  • 대상 서비스 또는 클라이언트에 기본 제공 재시도 메커니즘이 없는 경우 Polly와 같은 재시도 프레임워크를 사용하여 재시도를 관리하는 것이 좋습니다. 그러면 일관된 재시도 동작을 구현하는 데 도움이 되며 대상 서비스에 적합한 기본 재시도 전략을 제공할 수 있습니다. 그러나 일시적인 오류를 나타내기 위해 예외에 의존하지 않는 비표준 동작을 사용하는 서비스를 구현하거나, Retry-Response 회신을 사용하여 재시도 동작을 관리하려는 경우 사용자 지정 재시도 코드를 작성해야 할 수 있습니다.

  • 일시적인 검색 논리는 REST를 호출하는 데 사용하는 실제 클라이언트 API에 따라 달라집니다. 최신 HttpClient 클래스와 같은 일부 클라이언트는 성공이 아닌 HTTP 상태 코드를 사용하여 완료된 요청에 대한 예외를 throw하지 않습니다.

  • 서비스에서 반환된 HTTP 상태 코드는 오류가 일시적인지 여부를 나타내는 데 도움이 될 수 있습니다. 클라이언트 또는 재시도 프레임워크에서 생성된 예외를 검사하여 상태 코드에 액세스하거나 해당되는 예외 유형을 확인해야 할 수 있습니다. 다음 HTTP 코드는 일반적으로 재시도가 적합함을 나타냅니다.

    • 408 요청 시간 초과
    • 429 요청이 너무 많음
    • 500 내부 서버 오류
    • 502 잘못된 게이트웨이
    • 503 서비스를 사용할 수 없음
    • 504 게이트웨이 시간 초과
  • 재시도 논리가 예외를 기반으로 하는 경우 다음은 일반적으로 연결을 설정할 수 없는 일시적인 오류를 나타냅니다.

    • WebExceptionStatus.ConnectionClosed
    • WebExceptionStatus.ConnectFailure
    • WebExceptionStatus.Timeout
    • WebExceptionStatus.RequestCanceled
  • 서비스를 사용할 수 없음 상태의 경우 서비스는 Retry-After 응답 헤더 또는 다른 사용자 지정 헤더에서 재시도하기 전에 적절한 지연 시간을 나타낼 수 있습니다. 또한 서비스는 추가 정보를 사용자 지정 헤더로 전송하거나 응답의 내용에 포함할 수 있습니다.

  • 408 요청 시간 초과 및 429 너무 많은 요청을 제외하고 클라이언트 오류(4xx 범위의 오류)를 나타내는 상태 코드가 발생하면 재시도하지 마세요.

  • 서로 다른 네트워크 상태 및 다양한 시스템 부하와 같은 다양한 조건에서 재시도 전략 및 메커니즘을 철저히 테스트합니다.

재시도 전략

다음은 일반적인 재시도 전략 간격의 유형입니다.

  • 지수. 재시도 사이의 간격을 결정하는 무작위 추출 지수 백오프 방법을 사용하여 지정된 횟수의 재시도를 수행하는 재시도 정책입니다. 예를 들면 다음과 같습니다.

    var random = new Random();
    
    var delta = (int)((Math.Pow(2.0, currentRetryCount) - 1.0) *
                random.Next((int)(this.deltaBackoff.TotalMilliseconds * 0.8),
                (int)(this.deltaBackoff.TotalMilliseconds * 1.2)));
    var interval = (int)Math.Min(checked(this.minBackoff.TotalMilliseconds + delta),
                    this.maxBackoff.TotalMilliseconds);
    retryInterval = TimeSpan.FromMilliseconds(interval);
    
  • 증분. 재시도 횟수가 지정되고 재시도 간의 시간 간격이 증분되는 재시도 전략입니다. 예를 들면 다음과 같습니다.

    retryInterval = TimeSpan.FromMilliseconds(this.initialInterval.TotalMilliseconds +
                    (this.increment.TotalMilliseconds * currentRetryCount));
    
  • LinearRetry. 재시도 간에 지정된 고정 시간 간격을 사용하여 지정된 횟수의 재시도를 수행하는 재시도 정책입니다. 예를 들면 다음과 같습니다.

    retryInterval = this.deltaBackoff;
    

Polly를 통한 일시적인 오류 처리

Polly는 다시 시도 및 서킷 차단기 전략을 프로그래밍 방식으로 처리하는 라이브러리입니다. Polly 프로젝트는 .NET Foundation의 멤버입니다. Polly는 클라이언트가 기본적으로 재시도를 지원하지 않는 서비스의 유효한 대안이며 정확한 구현이 까다로운 사용자 지정 재시도 코드를 작성할 필요를 없애줍니다. Polly는 발생한 오류를 추적하는 방법도 제공하므로 재시도를 기록할 수 있습니다.

다음 단계