配置重试政策

适用于 Rust 的 Google Cloud 客户端库可以自动重试因暂时性错误而失败的操作。了解如何创建和自定义重试循环、为所有请求实现通用重试政策,以及针对特定请求替换默认政策。

前提条件

本指南中的示例使用 Secret Manager 服务。不过,这些概念同样适用于其他 Google Cloud 服务。

在继续操作之前,请按照使用 Secret Manager 创建和访问 Secret 中的说明启用 Secret Manager API 并进行身份验证。

依赖项

启用 Secret Manager 后,在 Cargo.toml 文件中声明依赖项:

cargo add google-cloud-secretmanager-v1

配置默认重试政策

本示例使用 Aip194Strict 政策。此政策基于 AIP-194 中的准则,该准则记录了 Google API 客户端应自动重试请求的条件。

如需将 Aip194Strict 政策设为服务的默认政策,请在客户端初始化期间设置该政策:

   let client = SecretManagerService::builder()
       .with_retry_policy(Aip194Strict)
       .build()
       .await?;

设置政策后,您可以照常使用该服务:

   let mut list = client
       .list_secrets()
       .set_parent(format!("projects/{project_id}"))
       .by_item();
   while let Some(secret) = list.next().await {
       let secret = secret?;
       println!("  secret={}", secret.name);
   }

配置默认重试政策:完整代码

此代码示例将 Aip194Strict 政策应用于 Secret Manager 服务。

use google_cloud_gax::paginator::ItemPaginator as _;
use google_cloud_gax::retry_policy::Aip194Strict;
use google_cloud_secretmanager_v1::client::SecretManagerService;

pub async fn sample(project_id: &str) -> anyhow::Result<()> {
   let client = SecretManagerService::builder()
       .with_retry_policy(Aip194Strict)
       .build()
       .await?;

   let mut list = client
       .list_secrets()
       .set_parent(format!("projects/{project_id}"))
       .by_item();
   while let Some(secret) = list.next().await {
       let secret = secret?;
       println!("  secret={}", secret.name);
   }

   Ok(())
}

配置具有限制的默认重试政策

默认情况下,Aip194Strict 政策不会限制重试次数或重试请求所花费的时间。不过,您可以为政策添加限制。

例如,您可以同时限制重试次数和重试循环中的时间:

   let client = SecretManagerService::builder()
       .with_retry_policy(
           Aip194Strict
               .with_attempt_limit(5)
               .with_time_limit(Duration::from_secs(15)),
       )
       .build()
       .await?;

使用此配置时,请求将照常运行:

   let mut list = client
       .list_secrets()
       .set_parent(format!("projects/{project_id}"))
       .by_item();
   while let Some(secret) = list.next().await {
       let secret = secret?;
       println!("  secret={}", secret.name);
   }

配置具有限制的默认重试政策:完整代码

此代码示例将 Aip194Strict 政策应用于 Secret Manager 服务,并设置了自定义尝试次数上限和时间上限。

use google_cloud_gax::paginator::ItemPaginator as _;
use google_cloud_gax::retry_policy::Aip194Strict;
use google_cloud_gax::retry_policy::RetryPolicyExt;
use google_cloud_secretmanager_v1::client::SecretManagerService;
use std::time::Duration;


pub async fn sample(project_id: &str) -> anyhow::Result<()> {
   let client = SecretManagerService::builder()
       .with_retry_policy(
           Aip194Strict
               .with_attempt_limit(5)
               .with_time_limit(Duration::from_secs(15)),
       )
       .build()
       .await?;


   let mut list = client
       .list_secrets()
       .set_parent(format!("projects/{project_id}"))
       .by_item();
   while let Some(secret) = list.next().await {
       let secret = secret?;
       println!("  secret={}", secret.name);
   }


   Ok(())
}

替换请求的重试政策

有时,应用需要针对特定请求替换重试政策。例如,应用开发者可能了解服务或应用的具体细节,并确定可以安全地容忍更多错误。

例如,删除密钥是幂等的,因为该操作只能成功一次。但客户端库会假定所有删除操作都是不安全的。您可以针对请求替换政策:

   client
       .delete_secret()
       .set_name(format!("projects/{project_id}/secrets/{secret_id}"))
       .with_retry_policy(
           AlwaysRetry
               .with_attempt_limit(5)
               .with_time_limit(Duration::from_secs(15)),
       )
       .send()
       .await?;

替换请求的重试政策:完整代码

此代码示例会针对 Secret Manager 服务的特定请求替换尝试次数限制和时间限制。

use google_cloud_gax::options::RequestOptionsBuilder;
use google_cloud_gax::retry_policy::AlwaysRetry;
use google_cloud_gax::retry_policy::RetryPolicyExt;
use google_cloud_secretmanager_v1::client::SecretManagerService;
use std::time::Duration;


pub async fn sample(
   client: &SecretManagerService,
   project_id: &str,
   secret_id: &str,
) -> anyhow::Result<()> {
   client
       .delete_secret()
       .set_name(format!("projects/{project_id}/secrets/{secret_id}"))
       .with_retry_policy(
           AlwaysRetry
               .with_attempt_limit(5)
               .with_time_limit(Duration::from_secs(15)),
       )
       .send()
       .await?;


   Ok(())
}