클라이언트 측 재시도 구성

Java용 Cloud 클라이언트 라이브러리는 재시도를 사용하여 예기치 않은 일시적인 오류(즉, 서버가 일시적으로 사용할 수 없음)를 처리합니다. 여러 번 시도하면 서버에서 성공적인 응답을 받을 수 있습니다.

기본 재시도 값은 클라우드 서비스를 운영하는 팀에서 선택합니다. 이러한 재시도 값은 RPC별로 구성됩니다. 서비스는 일부 RPC에 대해서만 재시도를 사용 설정할 수 있습니다. 서비스의 각 RPC가 다르게 구성될 수 있습니다.

재시도 매개변수

클라이언트 라이브러리에는 구성할 수 있는 두 가지 유형의 재시도 매개변수가 있습니다.

  1. 재시도 상태 코드: 재시도할 상태 코드 집합입니다.
  2. 재시도 시간 제한 또는 시도 범위: 범위를 정의하도록 구성 가능한 RetrySettings

기본 RPC 재시도 구성 위치

기본 재시도 구성은 생성된 {Client}StubSettings 파일에 정의되어 있습니다. Java-Asset v3.64.0의 ExportAssets RPC를 예로 들면 기본 재시도 구성은 다음 위치에 정의됩니다.

  • 재시도 상태 코드: AssetServiceStubSettings.java 파일에 구성됩니다. 예:

    ImmutableMap.Builder<String, ImmutableSet<StatusCode.Code>> definitions = ImmutableMap.builder();
    definitions.put("no_retry_0_codes", ImmutableSet.copyOf(Lists.<StatusCode.Code>newArrayList()));
    // ... More StatusCode configurations
    RETRYABLE_CODE_DEFINITIONS = definitions.build();
    
  • 재시도 매개변수: AssetServiceStubSettings.java 파일에 구성됩니다. 예:

    ImmutableMap.Builder<String, RetrySettings> definitions = ImmutableMap.builder();
    RetrySettings settings = null;
    settings =
        RetrySettings.newBuilder()
        .setInitialRpcTimeoutDuration(Duration.ofMillis(60000L))
        .setRpcTimeoutMultiplier(1.0)
        .setMaxRpcTimeoutDuration(Duration.ofMillis(60000L))
        .setTotalTimeoutDuration(Duration.ofMillis(60000L))
        .build();
    definitions.put("no_retry_0_params", settings);
    // ... More RetrySettings configurations
    RETRY_PARAM_DEFINITIONS = definitions.build();
    

두 구성 모두 AssetServiceStubSettings.java 파일의 RPC에 매핑됩니다. 예:

builder
  .exportAssetsSettings()
  .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes"))
  .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params"));

클라이언트 라이브러리 재시도 개념

재시도를 사용하면 RPC가 성공적인 호출을 달성하기 위해 여러 번 시도할 수 있습니다. 성공적인 호출은 서버에서 OK 상태 코드 (gRPC에서) 또는 2xx 상태 코드 (HttpJson에서)를 반환하는 응답입니다.

시도와 작업 비교

다음 RetrySettings 구성은 RPC 시도와 작업의 재시도 설정을 모두 수정합니다.

settings =
  RetrySettings.newBuilder()
      .setInitialRetryDelayDuration(Duration.ofMillis(100L))
      .setRetryDelayMultiplier(1.3)
      .setMaxRetryDelayDuration(Duration.ofMillis(60000L))
      .setInitialRpcTimeoutDuration(Duration.ofMillis(60000L))
      .setRpcTimeoutMultiplier(1.0)
      .setMaxRpcTimeoutDuration(Duration.ofMillis(60000L))
      .setTotalTimeoutDuration(Duration.ofMillis(60000L))
      .build();

RPC 시도는 이루어진 개별 시도이며 RPC 작업은 이루어진 모든 시도의 모음입니다. 단일 RPC 호출에는 단일 작업에서 하나 이상의 시도가 있습니다.

개별 RPC 경계 (시도)는 다음 설정에 의해 제어됩니다.

전체 RPC 경계 (작업)는 다음 설정에 의해 제어됩니다.

RPC가 재시도되는 경우

다음 두 시나리오가 모두 발생하면 RPC가 재시도됩니다.

  • 라이브러리에서 성공하지 못한 상태 코드를 수신하고 상태 코드가 다시 시도할 수 있는 것으로 표시됩니다.
  • RPC 호출이 개별 RPC 경계를 초과하지만 총 RPC 경계 내에 있습니다.

하나의 시나리오만 참이거나 두 시나리오 모두 참이 아닌 경우 RPC가 재시도되지 않습니다.

예를 들어 총 제한 시간이 초과되지 않았지만 최신 시도에서 다시 시도할 수 없는 상태 코드를 수신한 경우입니다.

또한 RPC 경계를 구성할 때 각 시도의 경계와 총 RPC의 경계를 구성할 수 있습니다. 재시도 알고리즘은 개별 시도의 범위가 전체 RPC의 범위 내에 있도록 합니다.

지수 백오프

지수 백오프는 각 재시도 시도 사이에 지연 시간을 늘려 요청을 재시도합니다. 이 재시도 지연 값은 최대 재시도 지연 값으로 제한될 수 있습니다.

예를 들어 다음 재시도 구성은 다음과 같은 지연 시간을 초래할 수 있습니다.

Initial Retry Delay: 100ms
Retry Delay Multiplier: 2.0
Max Retry Delay: 500ms
  • 시도 1: 100ms 지연
  • 시도 2: 200ms 지연
  • 시도 3: 지연 시간 400ms
  • 시도 4: 500ms 지연
  • ...
  • X 시도: 500ms 지연

지터

지터는 RPC가 호출되는 시점을 분산하기 위해 무작위성을 사용하여 분산을 추가합니다. Google Cloud 클라이언트 라이브러리는 항상 재시도에 지터를 사용 설정합니다. 이렇게 하면 서버에 과부하를 주지 않고 재시도 시도를 분산할 수 있습니다.

지터 무작위 값은 재시도 지연을 기반으로 계산됩니다. 각 시도 전에 재시도 알고리즘은 [1, RETRY_DELAY] 사이의 임의 값을 계산합니다. 이 계산된 값은 요청이 서버로 전송되기 전의 대략적인 지연 시간입니다.

다음 재시도 구성은 지터와 지수 백오프를 사용합니다.

Initial Retry Delay: 100ms
Retry Delay Multiplier: 2.0
Max Retry Delay: 500ms

이로 인해 다음과 같은 지연 시간이 발생할 수 있습니다.

  • 시도 1: [1, 100]ms 사이의 임의의 값을 지연합니다.
  • 두 번째 시도: [1, 200]ms 사이의 임의 값을 지연시킵니다.
  • 시도 3: [1, 400]ms 사이의 임의의 값을 지연합니다.
  • 시도 4: [1, 500]ms 사이의 임의의 값 지연
  • ...
  • X차 시도: [1, 500]ms 사이의 임의의 값을 지연합니다.

재시도 예시

다음 예에서는 일부 재시도 구성의 동작을 보여줍니다.

다시 시도하지 않음

이 예시에서는 재시도를 사용 중지합니다.

RetrySettings defaultNoRetrySettings =
    RetrySettings.newBuilder()
    // Use the default configurations for other settings
    .setTotalTimeoutDuration(Duration.ofMillis(5000L))
    // Explicitly set retries as disabled (maxAttempts == 1)
    .setMaxAttempts(1)
    .build();

또는 다음 예시를 사용하여 이 동작을 구성할 수 있습니다.

RetrySettings defaultNoRetrySettings =
    RetrySettings.newBuilder()
    .setLogicalTimeoutDuration(Duration.ofMillis(5000L))
    .build();

다음 표에는 시도가 표시됩니다.

시도 번호 RPC 제한 시간 다시 시도 간격 호출 호출됨 통화 종료됨
1 5000ms 0ms 0ms 5000ms

재시도 예시

이 예시에서는 지정된 지연 시간과 시간 제한으로 재시도를 사용 설정합니다.

RetrySettings.newBuilder()
    .setInitialRetryDelayDuration(Duration.ofMillis(200L))
    .setRetryDelayMultiplier(2.0)
    .setMaxRetryDelayDuration(Duration.ofMillis(500L))
    .setInitialRpcTimeoutDuration(Duration.ofMillis(1500L))
    .setRpcTimeoutMultiplier(2.0)
    .setMaxRpcTimeoutDuration(Duration.ofMillis(3000L))
    .setTotalTimeoutDuration(Duration.ofMillis(5000L))
    .build();

다음 표에는 시도가 표시됩니다.

시도 번호 RPC 제한 시간 다시 시도 간격 호출 호출됨 통화 종료됨
1 1500ms 0ms 0ms 1500ms
2 (재시도) 3000ms 200ms 1700ms 4,700ms
3 (재시도 시도 안 함) - 400ms - -

재시도 예: 총 시간 제한이 더 김

이 예는 첫 번째 재시도 예와 비슷하지만 추가 재시도 시도와 마지막 재시도 시도의 상한 RPC 시간 초과를 보여주기 위해 총 시간 초과가 더 깁니다.

RetrySettings.newBuilder()
    .setInitialRetryDelayDuration(Duration.ofMillis(200L))
    .setRetryDelayMultiplier(2.0)
    .setMaxRetryDelayDuration(Duration.ofMillis(500L))
    .setInitialRpcTimeoutDuration(Duration.ofMillis(1500L))
    .setRpcTimeoutMultiplier(2.0)
    .setMaxRpcTimeoutDuration(Duration.ofMillis(3000L))
    .setTotalTimeoutDuration(Duration.ofMillis(10000L))
    .build();

다음 표에는 시도가 표시됩니다.

시도 번호 RPC 제한 시간 다시 시도 간격 호출 호출됨 통화 종료됨
1 1500ms 0ms 0ms 1500ms
2 (재시도) 3000ms 200ms 1700ms 4,700ms
3 (재시도) 4900ms 400ms 5,100ms 10000ms

세 번째 재시도 RPC 제한 시간 값은 총 제한 시간 값으로 인해 제한됩니다. 이전 제한 시간 값 (3000ms)에 배수 (2.0)를 사용하면 RPC 제한 시간이 6000ms가 됩니다. 하지만 RPC 제한 시간은 총 제한 시간을 초과해서는 안 되며 '남은 시간' (10000 - 5100 = 4900)으로 줄어듭니다.

재시도 예: 상한이 있는 RPC 제한 시간

RetrySettings defaultRetrySettings =
    RetrySettings.newBuilder()
        .setInitialRetryDelayDuration(Duration.ofMillis(200L))
        .setRetryDelayMultiplier(2.0)
        .setMaxRetryDelayDuration(Duration.ofMillis(500L))
        .setInitialRpcTimeoutDuration(Duration.ofMillis(500L))
        .setRpcTimeoutMultiplier(2.0)
        .setMaxRpcTimeoutDuration(Duration.ofMillis(2000L))
        .setTotalTimeoutDuration(Duration.ofMillis(4000L))
        .build();

다음 표에는 시도가 표시됩니다.

시도 번호 RPC 제한 시간 다시 시도 간격 호출 호출됨 통화 종료됨
1 500ms 0ms 0ms 500ms
2 (재시도) 1000ms 200ms 700ms 1700ms
3 (재시도) 1900ms 400ms 2100ms 4000ms

RPC 시간 제한이 총 시간 제한을 초과하지 않도록 제한되는 또 다른 예입니다.

RPC의 맞춤 재시도 매개변수를 구성하는 방법

다음 예에서는 Java-Asset 클라이언트 라이브러리를 사용합니다.

  1. 맞춤 구성으로 RetrySettings 클래스를 만듭니다.

    RetrySettings customRetrySettings =
      RetrySettings.newBuilder()
        // ... Retry Configurations
        .build();
    RetrySettings customRetrySettings2 =
      RetrySettings.newBuilder()
        // ... Retry Configurations
        .build();
    
  2. 클라이언트의 StubSettings.Builder를 만들고 RPC에 맞게 구성합니다.

    AssetServiceStubSettings.Builder assetStubSettingsBuilder = AssetServiceStubSettings.newBuilder();
    assetStubSettingsBuilder
      .exportAssetsSettings()
      // Set your custom Retry Settings
      .setRetrySettings(customRetrySettings)
      // Set your custom Retryable Codes
      .setRetryableCodes(ImmutableSet.of(StatusCode.Code.DEADLINE_EXCEEDED));
    

    제공된 코드 스니펫은 AssetServiceClientExportAssets RPC에 맞춤 재시도 구성을 설정합니다. customRetrySettings에 구성된 재시도 설정을 사용하도록 ExportAssets RPC를 구성하고 재시도할 수 있는 코드를 DEADLINE_EXCEEDED로 설정합니다.

  3. 클라이언트의 설정을 assetSettings로 만듭니다. java AssetServiceSettings assetSettings = AssetServiceSettings.create(assetStubSettingsBuilder.build()); 4. 설정을 assetClient로 사용하여 클라이언트를 만듭니다. java try (AssetServiceClient assetClient = AssetServiceClient.create(assetSettings)) { ... }

구성하려는 각 RPC에 대해 2단계를 반복합니다. 예를 들면 다음과 같습니다.

AssetServiceStubSettings.Builder assetStubSettingsBuilder = AssetServiceStubSettings.newBuilder();
  
// Modify the retry params for ExportAssets RPC
assetStubSettingsBuilder
  .exportAssetsSettings()
  .setRetrySettings(customRetrySettings)
  .setRetryableCodes(ImmutableSet.of(StatusCode.Code.DEADLINE_EXCEEDED));

// Modify the retry params for ListAssets RPC
assetStubSettingsBuilder
  .listAssetsSettings()
  .setRetrySettings(customRetrySettings2)
  .setRetryableCodes(ImmutableSet.of(StatusCode.Code.UNAVAILABLE));

FAQ

다음은 클라이언트 재시도 동작에 관해 자주 묻는 질문입니다.

X번 재시도할 것으로 예상했지만 Y번 시도했습니다.

시간 초과 구성을 사용 중지하는 것과 함께 최대 시도 횟수를 명시적으로 지정하지 않으면 시도된 재시도 횟수가 일관되지 않을 수 있습니다. RPC 지연 시간의 지터 무작위 값으로 인해 요청이 실제로 전송되는 시점을 예측하기가 어렵습니다.

전체 제한 시간 값에 도달하기 전에 RPC에서 실패를 반환했습니다.

재시도 알고리즘은 각 재시도 시도 중에 지터링된 재시도 지연 값을 계산합니다. 계산된 재시도 지연 시간은 미래(즉, currentTime() + jitteredRetryDelay)에 실행되도록 예약됩니다. 예약된 시도 시간이 총 제한 시간을 초과하면 최종 재시도 시도가 이루어지지 않습니다.

맞춤 설정을 구성했는데 할당량 문제가 발생합니다.

RetrySettings가 너무 적극적으로 실행되도록 구성했을 수 있습니다. 기본 재시도 값은 서비스를 운영하는 팀에서 선택합니다.

재시도 간격이 더 길고 재시도 빈도가 낮아지도록 재시도 지연 시간 (초기 재시도 지연 시간 및 재시도 승수)을 늘리는 것이 좋습니다. 이렇게 하면 응답이 느려질 수 있습니다.

사용 사례에 따라 더 빠른 응답이나 더 잦은 재시도 시도가 필요할 수 있습니다. 이 경우 할당량 한도를 늘려 보세요.