本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
重試和逾時
適用於 Go 的 AWS SDK 可讓您設定 HTTP 服務請求的重試行為。根據預設,服務用戶端會使用 retry.Standard
適用於 Go 的 AWS SDK 提供 aws.Retryer
標準重試器
retry.Standardaws.Retryer實作。標準重試器是速率有限的重試器,具有可設定的嘗試次數上限,以及調整請求退避政策的功能。
下表定義此重試器的預設值:
| 屬性 | 預設 |
|---|---|
|
嘗試次數上限 |
3 |
|
最大退避延遲 |
20 秒 |
當調用您的請求時發生可重試錯誤時,標準重試器將使用其提供的組態來延遲請求,然後重試請求。重試會將 新增至請求的整體延遲,如果預設組態不符合您的應用程式需求,您必須設定重試器。
如需標準重試
NopRetryer
aws.NopRetryeraws.Retryer實作。叫用服務用戶端操作時,此重試器只會允許嘗試一次請求,而任何產生的錯誤都會傳回給呼叫應用程式。
自訂行為
SDK 提供一組協助程式公用程式,可包裝 aws.Retryer實作,並傳回以所需重試行為包裝的提供的重試程式。您可以根據您的應用程式需求,覆寫所有用戶端、每個用戶端或每個操作的預設重試器。若要查看顯示如何執行此操作的其他範例,請參閱重試
警告
如果使用 指定全域aws.Retryer實作config.WithRetryer,您必須確保傳回aws.Retryer每次調用的新執行個體。這將確保您不會在所有服務用戶端之間建立全域重試權杖儲存貯體。
限制最大嘗試次數
您可以使用 retry.AddWithMaxAttemptsaws.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)
限制最大退避延遲
您可以使用 retry.AddWithMaxBackoffDelayaws.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 錯誤代碼
您可以使用 retry.AddWithErrorCodesaws.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)
用戶端速率限制
在標準重試政策中 適用於 Go 的 AWS SDK 引入新的用戶端速率限制機制,以符合現代 SDKs的行為。這是由重試器選項
RateLimiter 會以具有設定容量的字符儲存貯體運作,其中操作嘗試失敗會使用字符。嘗試使用超過可用權杖而導致 QuotaExceededError
預設實作的參數化方式如下 (如何修改每個設定):
-
容量為 500 (使用 NewTokenRateLimit 在 StandardOptions 上設定 RateLimiter 的值) NewTokenRateLimit
-
逾時成本 10 個字符所造成的重試 (在 StandardOptions 上設定 RetryTimeoutCost)
-
其他錯誤導致的重試需要 5 個字符 (在 StandardOptions 上設定 RetryCost)
-
在第一次嘗試時成功的 操作會新增 1 個字符 (在 StandardOptions 上設定 NoRetryIncrement)
-
第 2 次或之後嘗試成功的操作不會新增任何字符
-
如果您發現預設行為不符合應用程式的需求,您可以使用 ratelimit.None
範例:修改速率限制器
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 的速率限制
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 }) }))
逾時
叫用服務用戶端操作時,您可以使用內容time.Duration使用內容之後設定逾時。WithTimeoutcontext.Context給 HTTP 傳輸用戶端。如果在叫用 操作時,傳遞到軟體開發套件的內容已取消或變成取消,軟體開發套件將不會進一步重試請求,並會返回呼叫應用程式。如果提供給 SDK 的內容遭到取消,您必須在應用程式中適當地處理內容取消。
設定逾時
下列範例示範如何設定服務用戶端操作的逾時。
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 }