

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 重試和逾時
<a name="configure-retries-timeouts"></a>

 適用於 Go 的 AWS SDK 可讓您設定 HTTP 服務請求的重試行為。根據預設，服務用戶端會使用 [retry.Standard](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#Standard) 做為其預設的 retryer。如果預設組態或行為不符合您的應用程式需求，您可以調整重試器組態或提供您自己的重試器實作。

 適用於 Go 的 AWS SDK 提供 [aws.Retryer](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Retryer) 界面，可定義要實作的重試實作所需的一組方法。開發套件提供兩種重試實作：[retry.Standard](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#Standard) 和 [aws.NoOpRetryer](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#NoOpRetryer)。

## 標準重試器
<a name="standard-retryer"></a>

 [retry.Standard](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#Standard) retryer 是 SDK 用戶端使用的預設`aws.Retryer`實作。標準重試器是速率有限的重試器，具有可設定的嘗試次數上限，以及調整請求退避政策的功能。

 下表定義此重試器的預設值：


| 屬性 | 預設 | 
| --- | --- | 
| 嘗試次數上限 | 3 | 
| 最大退避延遲 | 20 秒 | 

 當調用您的請求時發生可重試錯誤時，標準重試器將使用其提供的組態來延遲請求，然後重試請求。重試會將 新增至請求的整體延遲，如果預設組態不符合您的應用程式需求，您必須設定重試器。

 如需標準[重試](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry)器實作將哪些錯誤視為可重試的詳細資訊，請參閱重試套件文件。

## NopRetryer
<a name="nopretryer"></a>

 [aws.NopRetryer](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#NopRetryer) 是如果您想要停用所有重試嘗試時所提供的`aws.Retryer`實作。叫用服務用戶端操作時，此重試器只會允許嘗試一次請求，而任何產生的錯誤都會傳回給呼叫應用程式。

## 自訂行為
<a name="customizing-behavior"></a>

 SDK 提供一組協助程式公用程式，可包裝 `aws.Retryer`實作，並傳回以所需重試行為包裝的提供的重試程式。您可以根據您的應用程式需求，覆寫所有用戶端、每個用戶端或每個操作的預設重試器。若要查看顯示如何執行此操作的其他範例，請參閱[重試](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry)套件文件範例。

**警告**  
 如果使用 指定全域`aws.Retryer`實作`config.WithRetryer`，您必須確保傳回`aws.Retryer`每次調用的新執行個體。這將確保您不會在所有服務用戶端之間建立全域重試權杖儲存貯體。

### 限制最大嘗試次數
<a name="limiting-the-max-number-of-attempts"></a>

 您可以使用 [retry.AddWithMaxAttempts](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#AddWithMaxAttempts) 來包裝`aws.Retryer`實作，將最大嘗試次數設定為所需的值。

**警告**  
 使用 `retry.AddWithMaxAttempts`搭配值為零，將允許 SDK 重試所有可重試的錯誤，直到請求成功，或傳回不可重試的錯誤。**允許 SDK 無限重試可能會導致工作負載失控和計費週期膨脹。**

```
import "context"
import "github.com/aws/aws-sdk-go-v2/aws/retry"
import "github.com/aws/aws-sdk-go-v2/config"
import "github.com/aws/aws-sdk-go-v2/service/s3"

// ...

// MaxAttempts will be infinite (will retry indefinitely)
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryer(func() aws.Retryer {
    return retry.AddWithMaxAttempts(retry.NewStandard(), 0)
}))
if err != nil {
    return err
}

client := s3.NewFromConfig(cfg)
```

 請注意，使用功能選項直接設定 MaxAttempts 來執行個體化重試器的行為會略有不同。更具體地說，設定小於或等於零的值會導致重試器使用預設的嘗試次數上限 3 次，而不是無限次重試：

```
import "context"
import "github.com/aws/aws-sdk-go-v2/aws/retry"
import "github.com/aws/aws-sdk-go-v2/config"
import "github.com/aws/aws-sdk-go-v2/service/s3"

// ...

// MaxAttempts will default to 3
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryer(func() aws.Retryer {
    return retry.NewStandard(func(o *retry.StandardOptions) {
        o.MaxAttempts = 0
    })
}))
if err != nil {
    return err
}

client := s3.NewFromConfig(cfg)
```

### 限制最大退避延遲
<a name="limiting-the-max-back-off-delay"></a>

 您可以使用 [retry.AddWithMaxBackoffDelay](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#AddWithMaxBackoffDelay) 來包裝`aws.Retryer`實作，並限制重試失敗請求之間允許發生的最大退避延遲。

 例如，您可以下列程式碼，以 5 秒的所需最大延遲包裝標準用戶端重試器：

```
import "context"
import "time"
import "github.com/aws/aws-sdk-go-v2/aws/retry"
import "github.com/aws/aws-sdk-go-v2/config"
import "github.com/aws/aws-sdk-go-v2/service/s3"

// ...

cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryer(func() aws.Retryer {
    return retry.AddWithMaxBackoffDelay(retry.NewStandard(), time.Second*5)
}))
if err != nil {
    return err
}

client := s3.NewFromConfig(cfg)
```

### 重試其他 API 錯誤代碼
<a name="retry-additional-api-error-codes"></a>

 您可以使用 [retry.AddWithErrorCodes](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#AddWithErrorCodes) 來包裝`aws.Retryer`實作，並包含應視為可重試的其他 API 錯誤代碼。

 例如，您可以下列程式碼來包裝標準用戶端重試器，以包含可重試的 Amazon S3 `NoSuchBucketException`例外狀況。

```
import "context"
import "time"
import "github.com/aws/aws-sdk-go-v2/aws/retry"
import "github.com/aws/aws-sdk-go-v2/config"
import "github.com/aws/aws-sdk-go-v2/service/s3"
import "github.com/aws/aws-sdk-go-v2/service/s3/types"

// ...

cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryer(func() aws.Retryer {
    return retry.AddWithErrorCodes(retry.NewStandard(), (*types.NoSuchBucketException)(nil).ErrorCode())
}))
if err != nil {
    return err
}

client := s3.NewFromConfig(cfg)
```

### 用戶端速率限制
<a name="client-side-rate-limiting"></a>

 在標準重試政策中 適用於 Go 的 AWS SDK 引入新的用戶端速率限制機制，以符合現代 SDKs的行為。這是由重試器[選項](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#StandardOptions)上的 [RateLimiter](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#RateLimiter) 欄位所控制的行為。

 RateLimiter 會以具有設定容量的字符儲存貯體運作，其中操作嘗試失敗會使用字符。嘗試使用超過可用權杖而導致 [QuotaExceededError](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/ratelimit#QuotaExceededError) 操作失敗的重試。

 預設實作的參數化方式如下 （如何修改每個設定）：
+  容量為 500 （使用 NewTokenRateLimit 在 StandardOptions 上設定 RateLimiter 的值） [NewTokenRateLimit](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/ratelimit#NewTokenRateLimit) 
+  逾時成本 10 個字符所造成的重試 （在 StandardOptions 上設定 RetryTimeoutCost) 
+  其他錯誤導致的重試需要 5 個字符 （在 StandardOptions 上設定 RetryCost) 
+  在第一次嘗試時成功的 操作會新增 1 個字符 （在 StandardOptions 上設定 NoRetryIncrement) 
  +  第 2 次或之後嘗試成功的操作不會新增任何字符 

 如果您發現預設行為不符合應用程式的需求，您可以使用 [ratelimit.None](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/ratelimit#pkg-variables) 將其停用。

#### 範例：修改速率限制器
<a name="example-modified-rate-limiter"></a>

```
import (
    "context"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/aws/ratelimit"
    "github.com/aws/aws-sdk-go-v2/aws/retry"
    "github.com/aws/aws-sdk-go-v2/config"
)

// ...

cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRetryer(func() aws.Retryer {
    return retry.NewStandard(func(o *retry.StandardOptions) {
        // Makes the rate limiter more permissive in general. These values are
        // arbitrary for demonstration and may not suit your specific
        // application's needs.
        o.RateLimiter = ratelimit.NewTokenRateLimit(1000)
        o.RetryCost = 1
        o.RetryTimeoutCost = 3
        o.NoRetryIncrement = 10
    })
}))
```

#### 範例：沒有使用 ratelimit.None 的速率限制
<a name="example-no-rate-limit-using-ratelimitnone"></a>

```
import (
    "context"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/aws/ratelimit"
    "github.com/aws/aws-sdk-go-v2/aws/retry"
    "github.com/aws/aws-sdk-go-v2/config"
)

// ...

cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRetryer(func() aws.Retryer {
    return retry.NewStandard(func(o *retry.StandardOptions) {
        o.RateLimiter = ratelimit.None
    })
}))
```

## 逾時
<a name="timeouts"></a>

 叫用服務用戶端操作時，您可以使用[內容](https://golang.org/pkg/context/)套件來設定逾時或截止日期。使用 [內容。WithDeadline](https://golang.org/pkg/context/#WithDeadline) 可包裝您的應用程式內容，並將截止日期設定為必須完成調用操作的特定時間。在特定`time.Duration`使用[內容之後設定逾時。WithTimeout](https://golang.org/pkg/context/#WithTimeout)。軟體開發套件會在叫用服務 API 時，將提供的 傳遞`context.Context`給 HTTP 傳輸用戶端。如果在叫用 操作時，傳遞到軟體開發套件的內容已取消或變成取消，軟體開發套件將不會進一步重試請求，並會返回呼叫應用程式。如果提供給 SDK 的內容遭到取消，您必須在應用程式中適當地處理內容取消。

### 設定逾時
<a name="setting-a-timeout"></a>

 下列範例示範如何設定服務用戶端操作的逾時。

```
import "context"
import "time"

// ...

ctx := context.TODO() // or appropriate context.Context value for your application

client := s3.NewFromConfig(cfg)

// create a new context from the previous ctx with a timeout, e.g. 5 seconds
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()

resp, err := client.GetObject(ctx, &s3.GetObjectInput{
    // input parameters
})
if err != nil {
    // handle error
}
```