使用 Go 实现重试策略

在云中运行或与远程服务和资源通信的任何应用程序都必须能够处理暂时性故障。 这些应用程序经常因为网络连接瞬间断开、服务或资源繁忙时请求超时或其他因素而遇到故障。 开发人员应生成能够以透明方式处理暂时性故障的应用程序,以提高稳定性和复原能力。

本文介绍了如何使用适用于 Go 的 Azure 存储客户端模块为连接到 Azure Blob 存储的应用程序配置重试策略。 重试策略定义应用程序如何处理失败的请求,并始终根据应用程序的业务要求和故障性质得到优化。

配置重试选项

Blob 存储的重试策略是以编程方式配置的,让用户可以控制如何将重试选项应用于各种服务请求和方案。 例如,基于用户交互发出请求的 Web 应用可以实现一个重试次数较少且延迟较短的策略,以提高响应能力并在出错时通知用户。 或者,在后台运行批处理请求的应用或组件可以增加重试次数,并使用指数退避策略以允许请求时间成功完成。

下表列出了在 RetryOptions 实例中配置时可用的字段,以及类型、简要说明和默认值(如果未进行更改)。 应主动优化这些属性的值,以满足应用的需求。

属性 类型​​ 说明 默认值
MaxRetries int32 可选。 指定在产生错误之前重试失败操作的最大尝试次数。 小于零的值表示尝试一次且不重试。 3
TryTimeout time.Duration 可选。 指示任何单次尝试 HTTP 请求所允许的最长时间。 指定一个大于零的值以启用。 注意:将此字段设置为较小的值可能会导致 HTTP 请求过早超时。 默认已禁用。
RetryDelay time.Duration 可选。 指定在重试操作之前要使用的初始延迟量。 仅当 HTTP 响应不包含 Retry-After 标头时才使用该值。 延迟随着每次重试呈指数增加,直至达到 MaxRetryDelay 指定的最大值。 小于零的值表示重试之间无延迟。 4 秒
MaxRetryDelay time.Duration 可选。 指定在重试操作之前允许的最大延迟。 通常,该值大于或等于 RetryDelay 中指定的值。 小于零的值表示没有最大值。 60 秒
StatusCodes []int 可选。 指定指示应重试操作的 HTTP 状态代码。 指定值将替换默认值。 指定空切片会禁用 HTTP 状态代码的重试。 408 - http.StatusRequestTimeout
429 - http.StatusTooManyRequests
500 - http.StatusInternalServerError
502 - http.StatusBadGateway
503 - http.StatusServiceUnavailable
504 - http.StatusGatewayTimeout
ShouldRetry func(*http.Response, error) bool 可选。 评估重试策略是否应重试请求。 指定后,该函数将替代与重试策略中 HTTP 状态代码列表和错误检查的比较。 在调用 ShouldRetry 之前,仍会评估 ContextNonRetriable 错误。 *http.Responseerror 参数是互斥的,即,如果一个参数是 nil,则另一个参数不会是 nil。 返回值 true 表示应重试重试策略。

若要使用本文中的代码示例,请在你的代码中添加以下 import 路径:

import (
	"context"
	"time"

	"github.com/Azure/azure-sdk-for-go/sdk/azcore"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

在以下代码示例中,我们会在 RetryOptions 实例中配置重试选项,并将其包含在 ClientOptions 实例中以创建新的客户端对象:

options := azblob.ClientOptions{
	ClientOptions: azcore.ClientOptions{
		Retry: policy.RetryOptions{
			MaxRetries:    10,
			TryTimeout:    time.Minute * 15,
			RetryDelay:    time.Second * 1,
			MaxRetryDelay: time.Second * 60,
			StatusCodes:   []int{408, 429, 500, 502, 503, 504},
		},
	},
}

credential, err := azidentity.NewDefaultAzureCredential(nil)
handleError(err)

client, err := azblob.NewClient(accountURL, credential, &options)
handleError(err)

在此示例中,从 client 发出的每个服务请求都将使用 RetryOptions 结构中定义的重试选项。 此策略适用于客户端请求。 你可以根据应用的需求为服务客户端配置各种重试策略。