백오프 패턴으로 재시도 - AWS 규범적 지침

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

백오프 패턴으로 재시도

Intent

백오프 패턴을 사용한 재시도는 일시적인 오류로 인해 실패한 작업을 투명하게 재시도하여 애플리케이션 안정성을 향상시킵니다.

동기부여

분산 아키텍처에서는 서비스 조절, 일시적인 네트워크 연결 손실 또는 일시적인 서비스 가용성 장애로 인해 일시적인 오류가 발생할 수 있습니다. 이러한 일시적인 오류로 인해 실패한 작업을 자동으로 재시도하면 사용자 경험과 애플리케이션 레질리언스가 향상됩니다. 그러나 자주 재시도하면 네트워크 대역폭에 과부하가 걸리고 경합이 발생할 수 있습니다. 지수 백오프는 지정된 재시도 횟수만큼 대기 시간을 늘려 작업을 재시도하는 기술입니다.

적용 가능성

다음과 같은 경우 백오프 패턴과 함께 재시도를 사용하십시오.

  • 서비스는 과부하를 방지하기 위해 요청을 자주 제한하여 다음과 같은 결과를 초래합니다.429 요청이 너무 많음호출 프로세스에 대한 예외.

  • 네트워크는 분산 아키텍처에서 눈에 띄지 않는 역할을 하며 일시적인 네트워크 문제로 인해 장애가 발생합니다.

  • 호출 중인 서비스를 일시적으로 사용할 수 없어 장애가 발생했습니다. 이 패턴을 사용하여 백오프 타임아웃을 유발하지 않는 한 자주 재시도하면 서비스 성능이 저하될 수 있습니다.

문제 및 고려 사항

  • 임피던시: 메서드를 여러 번 호출해도 시스템 상태를 한 번 호출한 것과 동일한 효과가 있는 경우 해당 작업은 무력한 것으로 간주됩니다. 백오프 패턴과 함께 재시도를 사용할 때는 작업이 동일해야 합니다. 그렇지 않으면 부분 업데이트로 인해 시스템 상태가 손상될 수 있습니다.

  • 네트워크 대역폭: 너무 많은 재시도가 네트워크 대역폭을 차지하여 응답 시간이 느려질 경우 서비스 성능이 저하될 수 있습니다.

  • 실패가 빠른 시나리오: 일시적이지 않은 오류의 경우 장애 원인을 파악할 수 있다면 회로 차단기 패턴을 사용하여 빠르게 실패하는 것이 더 효율적입니다.

  • 백오프 속도: 기하급수적 백오프를 도입하면 서비스 타임아웃에 영향을 주어 최종 사용자의 대기 시간이 길어질 수 있습니다.

구현

고수준 아키텍처

다음 다이어그램은 성공적인 응답이 반환될 때까지 서비스 A가 서비스 B에 대한 호출을 재시도하는 방법을 보여줍니다. 서비스 B가 몇 번의 시도 후에도 성공적인 응답을 반환하지 않으면 서비스 A는 재시도를 중지하고 호출자에게 실패를 반환할 수 있습니다.

백오프 패턴을 사용한 재시도를 위한 고급 아키텍처

를 사용한 구현AWS서비스

다음 다이어그램은 고객 지원 플랫폼의 티켓 처리 워크플로를 보여줍니다. 불만이 있는 고객의 티켓은 티켓 우선 순위를 자동으로 높여 신속하게 처리됩니다. 더Ticket infoLambda 함수는 티켓 세부 정보를 추출하고 다음을 호출합니다.Get sentiment람다 함수 더Get sentimentLambda 함수는 설명을 다음 주소로 전달하여 고객 감정을 확인합니다.아마존 이해(표시되지 않음).

전화를 걸면Get sentimentLambda 함수가 실패하면 워크플로가 작업을 세 번 재시도합니다.AWS Step Functions백오프 값을 구성할 수 있도록 하여 지수적 백오프를 허용합니다.

이 예에서는 최대 세 번의 재시도가 1.5초의 증가 배율로 구성됩니다. 첫 번째 재시도가 3초 후에 발생하는 경우 두 번째 재시도는 3 x 1.5초 = 4.5초 후에 발생하고 세 번째 재시도는 4.5 x 1.5초 = 6.75초 후에 발생합니다. 세 번째 재시도가 실패하면 워크플로가 실패합니다. 백오프 로직에는 사용자 지정 코드가 필요하지 않습니다. 이 코드는 다음과 같이 구성으로 제공됩니다.AWS Step Functions.

다음과 같은 백오프 패턴으로 다시 시도하십시오.AWS서비스

샘플 코드

다음 코드는 백오프 패턴을 사용한 재시도의 구현을 보여줍니다.

public async Task DoRetriesWithBackOff() { int retries = 0; bool retry; do { //Sample object for sending parameters var parameterObj = new InputParameter { SimulateTimeout = "false" }; var content = new StringContent(JsonConvert.SerializeObject(parameterObj), System.Text.Encoding.UTF8, "application/json"); var waitInMilliseconds = Convert.ToInt32((Math.Pow(2, retries) - 1) * 100); System.Threading.Thread.Sleep(waitInMilliseconds); var response = await _client.PostAsync(_baseURL, content); switch (response.StatusCode) { //Success case HttpStatusCode.OK: retry = false; Console.WriteLine(response.Content.ReadAsStringAsync().Result); break; //Throttling, timeouts case HttpStatusCode.TooManyRequests: case HttpStatusCode.GatewayTimeout: retry = true; break; //Some other error occured, so stop calling the API default: retry = false; break; } retries++; } while (retry && retries < MAX_RETRIES); }

GitHub저장소

이 패턴에 대한 샘플 아키텍처의 전체 구현은 다음을 참조하십시오.GitHub리포지토리 주소https://github.com/aws-samples/retry-with-backoff.

관련 콘텐츠