기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
에서 재시도 AWS SDK for Kotlin
를 호출하여 예기치 않은 예외를 AWS 서비스 반환합니다. 통화를 재시도하면 제한 또는 일시적 오류와 같은 특정 유형의 오류가 성공할 수 있습니다.
이 페이지에서는가 재시도를 자동으로 AWS SDK for Kotlin 처리하는 방법과 애플리케이션의 재시도 동작을 사용자 지정하는 방법을 설명합니다.
재시도 동작 이해
다음 섹션에서는 SDK가 요청을 재시도할 시기와 재시도 가능한 것으로 간주되는 예외를 결정하는 방법을 설명합니다.
기본 재시도 구성
기본적으로 모든 서비스 클라이언트는 표준 재시도 전략으로 자동으로 구성됩니다. 기본 구성은 최대 3회 실패하는 호출을 시도합니다(초기 시도 + 2회 재시도). 각 호출 간의 중간 지연은 재시도 폭풍을 방지하기 위해 지수 백오프 및 무작위 지터로 구성됩니다. 이 구성은 대부분의 사용 사례에서 작동하지만 처리량이 많은 시스템과 같은 일부 상황에서는 적합하지 않을 수 있습니다.
SDK는 재시도 가능한 오류에 대해서만 재시도합니다. 재시도 가능한 오류의 예로는 소켓 제한 시간, 서비스 측 제한, 동시성 또는 낙관적 잠금 실패, 일시적인 서비스 오류가 있습니다. 누락되거나 유효하지 않은 파라미터, 인증/보안 오류 및 잘못된 구성 예외는 재시도 가능한 것으로 간주되지 않습니다.
최대 시도 횟수, 지연 및 백오프, 토큰 버킷 구성을 설정하여 표준 재시도 전략을 사용자 지정할 수 있습니다.
재시도할 수 있는 예외는 무엇입니까?
는 재시도할 수 있는 예외를 결정하는 미리 구성된 재시도 정책을 AWS SDK for Kotlin 사용합니다. 서비스 클라이언트 구성에는 재시도에 적용되는 정책을 지정하는 retryPolicy
속성이 있습니다. 사용자 지정 값을 지정하지 않으면 기본값은 AwsRetryPolicy입니다.
다음 예외는에 의해 재시도 가능한 것으로 결정됩니다. AwsRetryPolicy
오류 코드로 재시도 가능
sdkErrorMetadata.errorCode
의 ServiceException
이 있는 :
BandwidthLimitExceeded
EC2ThrottledException
IDPCommunicationError
LimitExceededException
PriorRequestNotComplete
ProvisionedThroughputExceededException
RequestLimitExceeded
RequestThrottled
RequestThrottledException
RequestTimeout
RequestTimeoutException
SlowDown
ThrottledException
Throttling
ThrottlingException
TooManyRequestsException
TransactionInProgressException
HTTP 상태 코드로 재시도 가능
sdkErrorMetadata.statusCode
의 ServiceException
이 있는 :
500(내부 서비스 오류)
502(잘못된 게이트웨이)
503(서비스 사용 불가)
504(게이트웨이 제한 시간)
오류 유형으로 재시도 가능
sdkErrorMetadata.errorType
의 ServiceException
이 있는 :
ErrorType.Server
(예: 내부 서비스 오류)ErrorType.Client
(예: 잘못된 요청, 리소스를 찾을 수 없음, 액세스 거부 등)
SDK 메타데이터로 재시도 가능
모든 SdkBaseException
위치:
sdkErrorMetadata.isRetryable
인 경우true
(예: 클라이언트 측 제한 시간, 네트워킹/소켓 오류 등)sdkErrorMetadata.isThrottling
인 경우true
(예: 짧은 시간 내에 너무 많은 요청을 하는 경우)
각 서비스 클라이언트에서 발생할 수 있는 예외의 전체 목록은 서비스별 API 참조 설명서를 참조하세요.
예외를 재시도할 수 있는지 확인
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") } } }
재시도 실패 시 코드에 도달하는 예외
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}") }
재시도 동작 사용자 지정
다음 섹션에서는 특정 사용 사례에 맞게 SDK의 재시도 동작을 사용자 지정하는 방법을 보여줍니다.
최대 시도 횟수 구성
클라이언트 구성 중에 retryStrategy
DSL 블록에서 기본 최대 시도 횟수(3)를 사용자 지정할 수 있습니다.
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy { maxAttempts = 5 } }
이전 코드 조각에 표시된 DynamoDB 서비스 클라이언트를 사용하면 SDK는 최대 5회(초기 시도 + 4회 재시도) 실패하는 API 호출을 시도합니다.
다음 코드 조각과 같이 최대 시도 횟수를 1로 설정하여 자동 재시도를 완전히 비활성화할 수 있습니다.
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy { maxAttempts = 1 // The SDK makes no retries. } }
지연 및 백오프 구성
재시도가 필요한 경우 기본 재시도 전략은 후속 시도를 수행하기 전에 대기합니다. 첫 번째 재시도의 지연 시간은 작지만 이후 재시도에서는 기하급수적으로 증가합니다. 최대 지연 시간은 너무 크게 증가하지 않도록 제한됩니다.
마지막으로 모든 시도 사이의 지연에 무작위 지터가 적용됩니다. 지터는 재시도 폭풍을 일으킬 수 있는 대규모 플릿의 영향을 완화하는 데 도움이 됩니다. (지수 백오프 및 지터에 대한 자세한 내용은이 AWS 아키텍처 블로그 게시물
지연 파라미터는 delayProvider
DSL 블록에서 구성할 수 있습니다.
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이면 계산된 지연 시간을 최대 절반까지 줄일 수 있습니다. 따라서 최대 10ms의 지연 시간을 5ms에서 10ms 사이로 줄일 수 있습니다. 값이 0.0이면 지터가 적용되지 않음을 의미합니다. 중요"Jitter 구성은 고급 기능입니다. 이 동작을 사용자 지정하는 것은 일반적으로 권장되지 않습니다. |
maxBackoff |
20초 | 모든 시도에 적용할 최대 지연 시간입니다. 이 값을 설정하면 후속 시도 사이에 발생하는 지수 증가가 제한되고 계산된 최대값이 너무 커지지 않습니다. 이 파라미터는 지터가 적용되기 전에 계산된 지연을 제한합니다. 지터를 적용하면 지연 시간이 훨씬 더 줄어들 수 있습니다. |
scaleFactor |
1.5 | 후속 최대 지연이 증가하는 지수 기반입니다. 예를 들어가
|
재시도 토큰 버킷 구성
기본 토큰 버킷 구성을 조정하여 표준 재시도 전략의 동작을 추가로 수정할 수 있습니다. 재시도 토큰 버킷은 성공 가능성이 낮거나 제한 시간 및 제한 실패와 같이 해결하는 데 더 많은 시간이 걸릴 수 있는 재시도를 줄이는 데 도움이 됩니다.
중요
토큰 버킷 구성은 고급 기능입니다. 이 동작을 사용자 지정하는 것은 일반적으로 권장되지 않습니다.
각 재시도(선택 사항으로 초기 시도 포함)는 토큰 버킷에서 일부 용량을 줄입니다. 감소되는 양은 시도 유형에 따라 달라집니다. 예를 들어 일시적 오류 재시도는 저렴할 수 있지만 제한 시간 재시도 또는 제한 오류로 인해 비용이 더 많이 들 수 있습니다.
시도가 성공하면 버킷에 용량이 반환됩니다. 버킷은 최대 용량을 초과하여 증가하거나 0 미만으로 감소할 수 없습니다.
useCircuitBreakerMode
설정 값에 따라는 용량을 0 미만으로 줄이려고 시도하면 다음 결과 중 하나가 발생합니다.
-
설정이 TRUE인 경우 예외가 발생합니다. 예를 들어 재시도가 너무 많아 더 많은 재시도가 성공할 가능성이 낮은 경우를 예로 들 수 있습니다.
-
설정이 FALSE인 경우 지연이 발생합니다. 예를 들어 버킷에 다시 충분한 용량이 있을 때까지 지연됩니다.
참고
회로 차단기가 활성화되면(토큰 버킷 용량이 0에 도달) SDK는 "재시도 용량 초과"라는 메시지ClientException
와 함께를 발생시킵니다. 이는 AWS 서비스가 아닌 SDK의 재시도 로직에서 시작AwsServiceException
되므로이 아닌 클라이언트 측 예외입니다. 예외는 작업을 시도하지 않고 즉시 발생하므로 서비스 중단 시 재시도 폭풍을 방지하는 데 도움이 됩니다.
토큰 버킷 파라미터는 tokenBucket
DSL 블록에서 구성할 수 있습니다.
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인 경우 토큰 버킷은 충분한 용량이 다시 채워질 때까지 시도를 지연시킵니다. |
회로 차단기 예외를 포함하여 재시도 시나리오 중에 발생하는 예외 유형에 대한 자세한 내용은 섹션을 참조하세요재시도 실패 시 코드에 도달하는 예외.
적응형 재시도 구성
표준 재시도 전략의 대안으로 적응형 재시도 전략은 제한 오류를 최소화하기 위해 이상적인 요청 속도를 찾는 고급 접근 방식입니다.
중요
적응형 재시도는 고급 재시도 모드입니다. 이 재시도 전략을 사용하는 것은 일반적으로 권장되지 않습니다.
적응형 재시도에는 표준 재시도의 모든 기능이 포함됩니다. 제한이 없는 요청과 비교하여 제한된 요청의 속도를 측정하는 클라이언트 측 속도 제한기를 추가합니다. 또한 트래픽을 제한하여 안전한 대역폭 내에 유지하려고 시도하므로 제한 오류가 발생하지 않는 것이 이상적입니다.
속도는 변화하는 서비스 조건 및 트래픽 패턴에 실시간으로 적응하며 그에 따라 트래픽 속도를 높이거나 낮출 수 있습니다. 트래픽이 많은 시나리오에서 속도 제한기가 초기 시도를 지연시킬 수 있습니다.
retryStrategy
메서드에 추가 파라미터를 제공하여 적응형 재시도 전략을 선택합니다. 속도 제한기 파라미터는 rateLimiter
DSL 블록에서 구성할 수 있습니다.
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy(AdaptiveRetryStrategy) { maxAttempts = 10 rateLimiter { minFillRate = 1.0 smoothing = 0.75 } } }
참고
적응형 재시도 전략은 클라이언트가 단일 리소스(예: DynamoDB 테이블 하나 또는 Amazon S3 버킷 하나)에 대해 작동한다고 가정합니다.
단일 클라이언트를 여러 리소스에 사용하는 경우 한 리소스와 연결된 제한 또는 중단으로 인해 클라이언트가 다른 모든 리소스에 액세스할 때 지연 시간이 증가하고 장애가 발생합니다. 적응형 재시도 전략을 사용하는 경우 각 리소스에 대해 단일 클라이언트를 사용하는 것이 좋습니다.