

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 에서 재시도 AWS SDK for Kotlin
<a name="retries"></a>

를 호출하여 예기치 않은 예외를 AWS 서비스 가끔 반환합니다. 직접 호출을 재시도하면 스로틀링 또는 일시적 오류와 같은 특정 유형의 오류가 성공할 수 있습니다.

이 페이지에서는가 자동으로 재시도를 AWS SDK for Kotlin 처리하는 방법과 애플리케이션의 재시도 동작을 사용자 지정하는 방법을 설명합니다.

## 재시도 동작 이해
<a name="retries-understanding"></a>

다음 섹션에서는 SDK가 요청을 재시도할 시기와 재시도 가능한 것으로 간주되는 예외를 결정하는 방법을 설명합니다.

### 기본 재시도 구성
<a name="retries-default"></a>

기본적으로 모든 서비스 클라이언트는 [표준 재시도 전략](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.retries/-standard-retry-strategy/index.html)으로 자동으로 구성됩니다. 기본 구성은 최대 3회 실패하는 호출을 시도합니다(초기 시도 \$1 2회 재시도). 각 호출 간의 개입 지연은 재시도 폭풍을 방지하기 위해 지수 백오프 및 무작위 지터로 구성됩니다. 이 구성은 대부분의 사용 사례에서 작동하지만 처리량이 많은 시스템과 같은 일부 상황에서는 적합하지 않을 수 있습니다.

SDK는 재시도 가능한 오류에 대해서만 재시도합니다. 재시도 가능한 오류의 예로는 소켓 제한 시간, 서비스 측 스로틀링, 동시성 또는 낙관적 잠금 실패, 일시적인 서비스 오류가 있습니다. 누락되거나 유효하지 않은 파라미터, 인증/보안 오류 및 잘못된 구성 예외는 재시도 가능한 것으로 간주되지 않습니다.

최대 시도 횟수, 지연 및 백오프, 토큰 버킷 구성을 설정하여 표준 재시도 전략을 사용자 지정할 수 있습니다.

### 어떤 예외를 재시도할 수 있나요?
<a name="retries-default-policy-details"></a>

는 재시도할 수 있는 예외를 결정하는 미리 구성된 재시도 정책을 AWS SDK for Kotlin 사용합니다. 서비스 클라이언트 구성에는 재시도에 적용되는 정책을 지정하는 `retryPolicy` 속성이 있습니다. 사용자 지정 값을 지정하지 않으면 기본값은 [AwsRetryPolicy](https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/aws-http/aws.sdk.kotlin.runtime.http.retries/-aws-retry-policy/)입니다.

다음 예외는에 의해 재시도 가능한 것으로 결정됩니다. `AwsRetryPolicy` 

#### 오류 코드로 재시도 가능
<a name="retries-retryable-by-error-code"></a>

`sdkErrorMetadata.errorCode`의 `ServiceException`이 있는 :
+ `BandwidthLimitExceeded`
+ `EC2ThrottledException`
+ `IDPCommunicationError`
+ `LimitExceededException`
+ `PriorRequestNotComplete`
+ `ProvisionedThroughputExceededException`
+ `RequestLimitExceeded`
+ `RequestThrottled`
+ `RequestThrottledException`
+ `RequestTimeout`
+ `RequestTimeoutException`
+ `SlowDown`
+ `ThrottledException`
+ `Throttling`
+ `ThrottlingException`
+ `TooManyRequestsException`
+ `TransactionInProgressException`

#### HTTP 상태 코드로 재시도 가능
<a name="retries-retryable-by-status-code"></a>

`sdkErrorMetadata.statusCode`의 `ServiceException`이 있는 :
+ 500(내부 서비스 오류)
+ 502(잘못된 게이트웨이)
+ 503(서비스 사용 불가)
+ 504(게이트웨이 제한 시간)

#### 오류 유형으로 재시도 가능
<a name="retries-retryable-by-error-type"></a>

`sdkErrorMetadata.errorType`의 `ServiceException`이 있는 :
+ `ErrorType.Server` (예: 내부 서비스 오류)
+ `ErrorType.Client` (예: 잘못된 요청, 리소스를 찾을 수 없음, 액세스 거부 등)

#### SDK 메타데이터로 재시도 가능
<a name="retries-retryable-by-metadata"></a>

모든 `SdkBaseException` 위치:
+ `sdkErrorMetadata.isRetryable` 인 경우`true`(예: 클라이언트 측 제한 시간, 네트워킹/소켓 오류 등)
+ `sdkErrorMetadata.isThrottling` 인 경우`true`(예: 짧은 시간 내에 너무 많은 요청을 하는 경우)

각 서비스 클라이언트에서 발생할 수 있는 예외의 전체 목록은 [서비스별 API 참조 설명서를](https://docs.aws.amazon.com/#products) 참조하세요.

### 예외를 재시도할 수 있는지 확인
<a name="retries-check-exception-retryable"></a>

SDK가 예외를 재시도 가능한 것으로 간주하는지 확인하려면 발견된 예외에 대해 `isRetryable` 속성을 확인합니다.

```
try {
    dynamoDbClient.putItem {
        tableName = "MyTable"
        item = mapOf("id" to AttributeValue.S("123"))
    }
} catch (e: SdkBaseException) {
    println("Exception occurred: ${e.message}")
    
    if (e.sdkErrorMetadata.isRetryable) {
        println("This exception is retryable - SDK will automatically retry")
        println("If you're seeing this, retries may have been exhausted")
    } else {
        println("This exception is not retryable - fix the underlying issue")
        
        // Common non-retryable scenarios.
        when {
            e.message?.contains("ValidationException") == true -> 
                println("Check your request parameters")
            e.message?.contains("AccessDenied") == true -> 
                println("Check your IAM permissions")
            e.message?.contains("ResourceNotFound") == true -> 
                println("Verify the resource exists")
        }
    }
}
```

### 재시도 실패 시 코드에 도달하는 예외
<a name="retries-exception-types-during-retries"></a>

SDK의 재시도 메커니즘으로 문제를 해결할 수 없는 경우 애플리케이션 코드에 예외가 발생합니다. 이러한 예외 유형을 이해하면 적절한 오류 처리를 구현하는 데 도움이 됩니다. 재시도를 트리거하는 예외는 *아닙니다*. 이러한 예외는 SDK에서 내부적으로 처리됩니다.

재시도가 소진되거나 비활성화되면 코드는 다음과 같은 유형의 예외를 포착합니다.

재시도 소진 후 서비스 예외  
모든 재시도가 실패하면 코드는 마지막 재시도가 실패한 최종 서비스 예외(의 하위 클래스`AwsServiceException`)를 포착합니다. 이는 제한 오류, 서버 오류 또는 SDK가 재시도를 통해 해결할 수 없는 기타 서비스별 예외일 수 있습니다.

재시도 소진 후 네트워크 예외  
모든 재시도 후에도 네트워크 문제가 지속되면 코드는 연결 제한 시간, DNS 해결 실패 및 SDK가 해결할 수 없는 기타 연결 문제와 같은 문제가 있는지 `ClientException` 인스턴스를 포착합니다.

다음 패턴을 사용하여 애플리케이션에서 이러한 예외를 처리합니다.

```
try {
    s3Client.getObject { 
        bucket = "amzn-s3-demo-bucket"
        key = "my-key" 
    }
} catch (e: AwsServiceException) {
    // Service-side errors that persisted through all retries.
    println("Service error after retries: ${e.errorDetails?.errorCode} - ${e.message}")
    
    // Handle specific service errors that couldn't be resolved.
    if (e.errorDetails?.errorCode == "ServiceQuotaExceededException" || 
        e.errorDetails?.errorCode == "ThrottlingException") {
        println("Rate limiting persisted - consider longer delays or quota increase")
    }
} catch (e: ClientException) {
    // Client-side errors (persistent network issues, DNS resolution failures, etc.)
    println("Client error after retries: ${e.message}")
}
```

## 재시도 동작 사용자 지정
<a name="retries-customizing"></a>

다음 섹션에서는 특정 사용 사례에 맞게 SDK의 재시도 동작을 사용자 지정하는 방법을 보여줍니다.

### 최대 시도 횟수 구성
<a name="retires-max-attempts"></a>

클라이언트 구성 중에 [`retryStrategy` DSL 블록](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.retries/-standard-retry-strategy/-config/-builder/index.html)에서 기본 최대 시도 횟수(3)를 사용자 지정할 수 있습니다.

```
val dynamoDb = DynamoDbClient.fromEnvironment {
    retryStrategy {
        maxAttempts = 5
    }
}
```

이전 코드 조각에 표시된 DynamoDB 서비스 클라이언트를 사용하면 SDK는 최대 5회 실패하는 API 호출을 시도합니다(초기 시도 \$1 4회 재시도).

다음 코드 조각과 같이 최대 시도 횟수를 1로 설정하여 자동 재시도를 완전히 비활성화할 수 있습니다.

```
val dynamoDb = DynamoDbClient.fromEnvironment {
    retryStrategy {
        maxAttempts = 1  // The SDK makes no retries.
    }
}
```

### 지연 및 백오프 구성
<a name="retries-delays-backoff"></a>

재시도가 필요한 경우 기본 재시도 전략은 후속 시도를 수행하기 전에 대기합니다. 첫 번째 재시도의 지연 시간은 짧지만 이후 재시도에서는 기하급수적으로 증가합니다. 최대 지연 시간은 너무 크게 증가하지 않도록 제한됩니다.

마지막으로 모든 시도 사이의 지연에 무작위 지터가 적용됩니다. 지터는 재시도 폭풍을 일으킬 수 있는 대규모 플릿의 영향을 완화하는 데 도움이 됩니다. (지수 백오프 및 지터에 대한 자세한 내용은이 [AWS 아키텍처 블로그 게시물](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/)을 참조하세요.)

지연 파라미터는 [`delayProvider` DSL 블록](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.retries.delay/-exponential-backoff-with-jitter/-config/index.html)에서 구성할 수 있습니다.

```
val dynamoDb = DynamoDbClient.fromEnvironment {
    retryStrategy {
        delayProvider {
            initialDelay = 100.milliseconds
            maxBackoff = 5.seconds
        }
    }
}
```

이전 코드 조각에 표시된 구성을 사용하면 클라이언트가 최대 100밀리초 동안 첫 번째 재시도를 지연합니다. 재시도 사이의 최대 시간은 5초입니다.

다음 파라미터를 사용하여 지연 및 백오프를 조정할 수 있습니다.


| 파라미터 | 기본값  | 설명 | 
| --- | --- | --- | 
| initialDelay | 10밀리초 | 첫 번째 재시도의 최대 지연 시간입니다. 지터를 적용하면 실제 지연 시간이 더 적을 수 있습니다. | 
| jitter | 1.0(전체 지터) |  계산된 지연을 임의로 줄이는 최대 진폭입니다. 기본값인 1.0은 계산된 지연을 최대 100%(예: 0까지)까지 줄일 수 있음을 의미합니다. 값이 0.5이면 계산된 지연 시간을 최대 절반까지 줄일 수 있습니다. 따라서 최대 10밀리초의 지연 시간을 5밀리초에서 10밀리초 사이로 줄일 수 있습니다. 값이 0.0이면 지터가 적용되지 않음을 의미합니다.  "Jitter 구성은 고급 기능입니다. 이 동작을 사용자 지정하는 것은 일반적으로 권장되지 않습니다.   | 
| maxBackoff | 20초 | 모든 시도에 적용할 최대 지연 시간입니다. 이 값을 설정하면 후속 시도 사이에 발생하는 지수 증가가 제한되고 계산된 최대값이 너무 커지지 않습니다. 이 파라미터는 지터가 적용되기 전에 계산된 지연을 제한합니다. 지터를 적용하면 지연 시간이 훨씬 더 줄어들 수 있습니다. | 
| scaleFactor | 1.5 | 후속 최대 지연이 증가하는 지수 기반입니다. 예를 들어 `initialDelay`가 10ms이고가 `scaleFactor` 1.5인 경우 다음과 같은 최대 지연 시간이 계산됩니다.[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/sdk-for-kotlin/latest/developer-guide/retries.html)지터를 적용하면 각 지연의 실제 양이 더 적을 수 있습니다. | 

### 재시도 토큰 버킷 구성
<a name="retries-token-bucket"></a>

기본 토큰 버킷 구성을 조정하여 표준 재시도 전략의 동작을 추가로 수정할 수 있습니다. 재시도 토큰 버킷은 성공 가능성이 낮거나 제한 시간 및 제한 실패와 같이 해결하는 데 더 많은 시간이 걸릴 수 있는 재시도를 줄이는 데 도움이 됩니다.

**중요**  
토큰 버킷 구성은 고급 기능입니다. 이 동작을 사용자 지정하는 것은 일반적으로 권장되지 않습니다.

각 재시도(선택 사항으로 초기 시도 포함)는 토큰 버킷에서 일부 용량을 줄입니다. 감소되는 양은 시도 유형에 따라 다릅니다. 예를 들어 일시적 오류 재시도는 저렴할 수 있지만 제한 시간 재시도 또는 제한 오류로 인해 비용이 더 많이 들 수 있습니다.

시도가 성공하면 버킷에 용량이 반환됩니다. 버킷은 최대 용량을 초과하여 증가하거나 0 미만으로 감소할 수 없습니다.

`useCircuitBreakerMode` 설정 값에 따라는 용량을 0 미만으로 줄이려고 시도하면 다음 결과 중 하나가 발생합니다.
+ 설정이 TRUE인 경우 예외가 발생합니다. 예를 들어 재시도가 너무 많아서 재시도가 성공할 가능성이 낮은 경우가 있습니다.
+ 설정이 FALSE인 경우 지연이 발생합니다. 예를 들어 버킷에 다시 충분한 용량이 있을 때까지 지연됩니다.

**참고**  
회로 차단기가 활성화되면(토큰 버킷 용량이 0에 도달) SDK는 "재시도 용량 초과"라는 메시지`ClientException`와 함께를 발생시킵니다. 이는 AWS 서비스가 아닌 SDK의 재시도 로직에서 시작`AwsServiceException`되므로이 아닌 클라이언트 측 예외입니다. 예외는 작업을 시도하지 않고 즉시 발생하므로 서비스 중단 시 재시도 폭풍을 방지하는 데 도움이 됩니다.

토큰 버킷 파라미터는 [`tokenBucket` DSL 블록](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.retries.delay/-standard-retry-token-bucket/-config/index.html)에서 구성할 수 있습니다.

```
val dynamoDb = DynamoDbClient.fromEnvironment {
    retryStrategy {
        tokenBucket {
            maxCapacity = 100
            refillUnitsPerSecond = 2
        }
    }
}
```

재시도 토큰 버킷을 튜닝하는 데 사용할 수 있는 파라미터는 다음과 같습니다.


| 파라미터 | 기본값  | 설명 | 
| --- | --- | --- | 
| initialTryCost | 0 | 초기 시도에 대해 버킷에서 줄일 양입니다. 기본값 0은 용량이 감소하지 않으므로 초기 시도가 중지되거나 지연되지 않음을 의미합니다. | 
| initialTrySuccessIncrement | 1 | 초기 시도가 성공했을 때 용량을 늘리는 양입니다. | 
| maxCapacity | 500 | 토큰 버킷의 최대 용량입니다. 사용 가능한 토큰 수는이 수를 초과할 수 없습니다. | 
| refillUnitsPerSecond | 0 | 초당 버킷에 다시 추가된 용량입니다. 값이 0이면 용량이 자동으로 다시 추가되지 않음을 의미합니다. (예를 들어 시도가 성공하면 용량이 증가합니다.) 값이 0이면 TRUE여야 useCircuitBreakerMode 합니다. | 
| retryCost | 5 | 일시적인 실패 후 시도 시 버킷에서 감소하는 양입니다. 시도가 성공하면 동일한 양이 버킷으로 다시 증가합니다. | 
| timeoutRetryCost | 10 | 제한 시간 초과 또는 제한 실패 후 시도 시 버킷에서 감소하는 양입니다. 시도가 성공하면 동일한 양이 버킷으로 다시 증가합니다. | 
| useCircuitBreakerMode | TRUE | 용량을 줄이려고 할 때 버킷의 용량이 0 미만으로 떨어질 때의 동작을 결정합니다. TRUE인 경우 토큰 버킷은 더 이상 재시도 용량이 존재하지 않음을 나타내는 예외를 발생시킵니다. FALSE인 경우 토큰 버킷은 충분한 용량이 다시 채워질 때까지 시도를 지연시킵니다. | 

회로 차단기 예외를 포함하여 재시도 시나리오 중에 발생하는 예외 유형에 대한 자세한 내용은 섹션을 참조하세요[재시도 실패 시 코드에 도달하는 예외](#retries-exception-types-during-retries).

### 적응형 재시도 구성
<a name="retries-adaptive-retries"></a>

표준 재시도 전략의 대안으로 적응형 재시도 전략은 제한 오류를 최소화하기 위해 이상적인 요청 속도를 찾는 고급 접근 방식입니다.

**중요**  
적응형 재시도는 고급 재시도 모드입니다. 이 재시도 전략을 사용하는 것은 일반적으로 권장되지 않습니다.

적응형 재시도에는 표준 재시도의 모든 기능이 포함됩니다. 비스로틀링 요청과 비교하여 스로틀링 요청의 속도를 측정하는 클라이언트 측 속도 제한 도구를 추가합니다. 또한 트래픽을 제한하여 안전한 대역폭 내에 유지하려는 시도로 스로틀링 오류가 발생하지 않는 것이 이상적입니다.

속도는 변화하는 서비스 조건 및 트래픽 패턴에 실시간으로 적응하며 그에 따라 트래픽 속도를 높이거나 낮출 수 있습니다. 트래픽이 많은 시나리오에서는 속도 제한 도구가 초기 시도를 지연시킬 수 있습니다.

`retryStrategy` 메서드에 추가 파라미터를 제공하여 적응형 재시도 전략을 선택합니다. 속도 제한기 파라미터는 [`rateLimiter` DSL 블록](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.retries.delay/-adaptive-rate-limiter/-config/index.html)에서 구성할 수 있습니다.

```
val dynamoDb = DynamoDbClient.fromEnvironment {
    retryStrategy(AdaptiveRetryStrategy) {
        maxAttempts = 10
        rateLimiter {
            minFillRate = 1.0
            smoothing = 0.75
        }
    }
}
```

**참고**  
적응형 재시도 전략은 클라이언트가 단일 리소스(예: DynamoDB 테이블 하나 또는 Amazon S3 버킷 하나)에 대해 작동한다고 가정합니다.  
단일 클라이언트를 여러 리소스에서 사용하는 경우 한 리소스와 연결된 스로틀링 또는 중단으로 인해 클라이언트가 다른 모든 리소스에 액세스할 때 지연 시간이 증가하고 장애가 발생합니다. 적응형 재시도 전략을 사용하는 경우 각 리소스에 대해 단일 클라이언트를 사용하는 것이 좋습니다.