- 示例工程
- 教程
- 后端
【免费下载链接】aws-doc-sdk-examples
Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.
本指南以 aws-doc-sdk-examples 仓库中的 Aurora 示例为主体,讲解如何使用 AWS SDK for Rust 完成 Amazon Aurora 的核心管理操作:从最基础的DescribeDBClusters快速入门,到"创建自定义集群参数组 → 修改参数 → 创建 DB 集群与实例 → 生成快照 → 清理资源"的完整集群生命周期场景。读完本文,你将掌握 Aurora MySQL 在 Rust 侧的 API 调用方式、参数组的深层作用机制,以及如何用cargo run与cargo test运行和验证这些示例。
示例代码在哪里
仓库中 Aurora 的 Rust 示例原本位于rust_dev_preview/examples/aurora目录,该目录下的 README 现仅保留一条迁移说明,将读者指向同一仓库内迁移后的完整代码位置:rustv1/examples/aurora/。迁移后的目录结构如下:
- README.md:示例总览、代码清单与运行说明;
- Cargo.toml:依赖清单(
aws-sdk-rds、tokio、anyhow、secrecy、inquire、mockall等); - src/lib.rs:库入口,导出
aurora_scenario与rds两个模块; - src/rds.rs:RDS API 的薄封装层,所有
aws_sdk_rds调用集中于此; - src/aurora_scenario/mod.rs:集群生命周期场景的编排逻辑;
- src/aurora_scenario/tests.rs:基于
mockall的单元测试; - src/bin/hello-world.rs 与 src/bin/aurora-scenario.rs:两个可执行二进制程序。
该目录的 README 明确说明,示例使用 AWS SDK for Rust 操作 Amazon Aurora。Aurora 是面向云构建的托管关系数据库引擎,兼容 MySQL 与 PostgreSQL,属于 Amazon RDS 的一部分。当前仓库中的场景示例默认使用aurora-mysql引擎。
前提条件与运行环境
账号与工具链
根据 rustv1/README.md 与 Aurora 示例 README,运行示例需要:
- 一个 AWS 账号,并已按 AWS SDK for Rust 官方入门指南配置好默认凭据与默认 Region(默认读取环境变量或
~/.aws配置中的 profile); - 安装 Cargo 构建工具(通常通过 rustup 安装);
- 注意:运行本示例可能产生 AWS 账户费用,运行测试同样可能产生费用。
常用环境变量
rustv1目录下的示例使用tracing_subscriber+env_filter输出运行日志,因此RUST_LOG是调试的关键变量:
RUST_LOG=info:显示程序运行的主要输出;RUST_LOG={crate_name}=debug:显示某个 crate 内部的动作细节;RUST_LOG=aws_smithy_http_tower::dispatch=trace:打印每次 AWS SDK 请求的完整 HTTP 请求;RUST_LOG=aws_smithy_http::middleware=trace:打印每次调用的完整 HTTP 响应。
AWS SDK for Rust 还会读取以下与凭据/区域相关的环境变量:
AWS_REGION(或AWS_DEFAULT_REGION):请求发往的 AWS 区域;AWS_PROFILE:使用的 AWS CLI 配置文件名(缺省为default);AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY:访问密钥对。
依赖清单解读
Cargo.toml 中与业务强相关的依赖如下:
aws-config = { version = "1.0.1", features = ["behavior-version-latest"] }:SDK 配置加载;aws-sdk-rds = { version = "1.3.0" }:RDS/Aurora 服务 SDK;tokio(full、test-util特性):异步运行时,test-util用于测试中对虚拟时钟的控制;secrecy = "0.8.0":用SecretString包装主用户密码,避免明文散落在内存调试信息中;inquire = "0.6.2":交互式命令行选择/输入(引擎族、版本、实例规格、用户名密码等);mockall = "0.11.4":单元测试 mock;sdk-examples-test-utils = { path = "../../test-utils" }:提供Waiter轮询工具(位于 rustv1/test-utils)。
Hello Aurora:三分钟跑通 DescribeDBClusters
hello-world.rs 是进入 Aurora 的起点,演示最基本的DescribeDBClusters调用:
#[tokio::main] async fn main() -> Result<(), Error> { tracing_subscriber::fmt::init(); let sdk_config = aws_config::from_env().load().await; let client = Client::new(&sdk_config); let describe_db_clusters_output = client .describe_db_clusters() .send() .await .map_err(|e| Error(e.to_string()))?; println!( "Found {} clusters:", describe_db_clusters_output.db_clusters().len() ); for cluster in describe_db_clusters_output.db_clusters() { let name = cluster.database_name().unwrap_or("Unknown"); let engine = cluster.engine().unwrap_or("Unknown"); let id = cluster.db_cluster_identifier().unwrap_or("Unknown"); let class = cluster.db_cluster_instance_class().unwrap_or("Unknown"); println!("\tDatabase: {name}"); println!("\t Engine: {engine}"); println!("\t ID: {id}"); println!("\tInstance: {class}"); } Ok(()) }这段代码展示了 SDK for Rust 的标准用法:aws_config::from_env().load().await加载凭据与区域配置 → 构建Client→ 链式设置请求参数(此处为空)→send().await发起调用。运行方式:
cargo run --bin hello-world输出会列出当前账号下所有 Aurora/RDS 集群的数据库名、引擎、集群标识符与实例规格;没有集群时会打印Found 0 clusters:。README 将其定位为 "Get started" 示例,对应的服务动作就是DescribeDBClusters。
核心场景:Learn the basics,完整走一遍集群生命周期
Aurora 示例 README 的 "Basics" 部分定义了一个名为 "Learn the basics" 的场景(对应 aurora_scenario/mod.rs 与 aurora-scenario.rs),其目标操作序列为:
- 创建一个自定义 Aurora DB 集群参数组,并设置参数值;
- 创建一个使用该参数组的 DB 集群;
- 创建一个包含数据库的 DB 实例;
- 对 DB 集群创建快照,然后清理资源。
入口二进制为aurora-scenario,运行方式:
cargo run --bin aurora-scenario整个程序通过inquire提供交互式提示,按以下流程推进。
第一步:选择引擎族与版本(get_engines + set_engine)
prepare_scenario先调用scenario.get_engines(),内部执行DescribeDbEngineVersions(Engine='aurora-mysql'),把返回结果中每个DBEngineVersion的db_parameter_group_family与engine_version组装成HashMap<String, Vec<String>>(引擎族 → 可用版本列表),从源码注释可知典型结果形如{aurora-mysql8.0, aurora-mysql5.7}。随后用inquire::Select让用户先选引擎族、再选版本。
选定引擎与版本后调用set_engine(engine, version),其核心逻辑在 aurora_scenario/mod.rs:
pub async fn set_engine(&mut self, engine: &str, version: &str) -> Result<(), ScenarioError> { self.engine_family = Some(engine.to_string()); self.engine_version = Some(version.to_string()); let create_db_cluster_parameter_group = self .rds .create_db_cluster_parameter_group( DB_CLUSTER_PARAMETER_GROUP_NAME, DB_CLUSTER_PARAMETER_GROUP_DESCRIPTION, engine, ) .await; ... }其中三个常量定义在 mod.rs:
DB_ENGINE = "aurora-mysql";DB_CLUSTER_PARAMETER_GROUP_NAME = "RustSDKCodeExamplesDBParameterGroup";DB_CLUSTER_PARAMETER_GROUP_DESCRIPTION = "Parameter Group created by Rust SDK Code Example";- 另有
DB_CLUSTER_IDENTIFIER = "RustSDKCodeExamplesDBCluster"与DB_INSTANCE_IDENTIFIER = "RustSDKCodeExamplesDBInstance"。
set_engine对DBParameterGroupAlreadyExists错误做了幂等处理:若参数组已存在则直接跳过创建,保证场景可重复运行。
第二步:选择实例规格(get_instance_classes)
引擎确定后,prepare_scenario调用scenario.get_instance_classes(),内部执行DescribeOrderableDbInstanceOptions(Engine='aurora-mysql', EngineVersion=<所选版本>),使用分页器收集所有可用规格,并过滤storage_type == "aurora"的项后提取db_instance_class(见 mod.rs)。用户通过交互式选择指定实例规格(如m5.large,测试用例中即使用该规格)。
第三步:展示并修改集群参数(cluster_parameters + update_auto_increment)
prepare_cluster先调用show_parameters,其内部执行DescribeDbClusterParameters(DBClusterParameterGroupName=...),由于参数列表很长,底层封装使用分页器收集全部页(见 rds.rs),随后在场景层用phf静态集合FILTER_PARAMETER_NAMES只筛选出两个关键参数(mod.rs):
auto_increment_offsetauto_increment_increment
筛选结果被包装为AuroraScenarioParameter,以参数名: 当前值 (allowed: 允许值)的格式打印,方便用户看到可选项。
接着程序用inquire::Text分别询问这两个参数的更新值(默认auto_increment_offset=5、auto_increment_increment=3),随后调用scenario.update_auto_increment(offset, increment)。这一步的核心在 mod.rs:通过一次ModifyDbClusterParameterGroup调用同时修改两个参数,且都使用ApplyMethod::Immediate(立即生效,无需重启实例):
let modify_db_cluster_parameter_group = self .rds .modify_db_cluster_parameter_group( DB_CLUSTER_PARAMETER_GROUP_NAME, vec![ Parameter::builder() .parameter_name("auto_increment_offset") .parameter_value(format!("{offset}")) .apply_method(aws_sdk_rds::types::ApplyMethod::Immediate) .build(), Parameter::builder() .parameter_name("auto_increment_increment") .parameter_value(format!("{increment}")) .apply_method(aws_sdk_rds::types::ApplyMethod::Immediate) .build(), ], ) .await;修改完成后再次调用show_parameters展示新值,形成"读取-修改-回读验证"的闭环。
第四步:设置数据库登录信息
程序提示输入数据库用户名(默认testuser)与密码,密码通过inquire的 validator 强制至少 8 个字符,否则拒绝输入;密码以SecretString包装后保存到场景对象中(见 aurora-scenario.rs)。
第五步:创建集群与实例并等待就绪(start_cluster_and_instance)
run_instance首先调用scenario.start_cluster_and_instance(),这是整个场景中最复杂的步骤(mod.rs),内部完成:
创建 DB 集群:
CreateDBCluster,传入集群标识符、参数组名、引擎aurora-mysql、所选版本、主用户名与主用户密码;在集群内创建 DB 实例:
CreateDBInstance,传入集群标识符、实例标识符、实例规格与引擎;等待就绪:因为集群创建最长可能耗时 20 分钟,代码用
sdk-examples-test-utils提供的Waiter构建最长 20 分钟的轮询(Duration::from_secs(20 * 60)),在循环中同时检查:DescribeDbClusters返回的集群状态;DescribeDbInstances中所有实例的DBInstanceStatus == "Available";DescribeDbClusterEndpoints中所有端点的status == "available"。
let instances_available = instance .unwrap() .db_instances() .iter() .all(|instance| instance.db_instance_status() == Some("Available")); let endpoints_available = endpoints .unwrap() .db_cluster_endpoints() .iter() .all(|endpoint| endpoint.status() == Some("available")); if instances_available && endpoints_available { return Ok(()); }只有三者全部就绪才算集群可用,这是 Aurora "集群 + 实例 + 端点" 三态并发的典型等待逻辑。轮询期间某次
DescribeDbClusters失败只会记录 warn 日志并继续下一次循环,而不是直接终止。
第六步:输出连接串并使用数据库
集群就绪后,scenario.connection_string()从DescribeDbClusters结果中取出集群端点、端口与主用户名,拼出可直接使用的 MySQL 客户端命令(mod.rs):
Ok(format!("mysql -h {endpoint} -P {port} -u {username} -p"))程序打印该连接串并暂停等待用户操作数据库("Use the database with the connection string. When you're finished, press enter key to continue.")。
第七步:创建集群快照(snapshot)
用户按回车后,程序询问快照名称(默认ScenarioRun),然后调用scenario.snapshot(name),内部执行CreateDbClusterSnapshot,快照标识符由"集群标识符 +_+ 用户输入名"拼接而成(如RustSDKCodeExamplesDBCluster_ScenarioRun),成功后打印快照 ARN(mod.rs)。
第八步:清理资源(clean_up)
场景最后调用scenario.clean_up()(mod.rs),按依赖顺序逆向删除并等待,任何一步失败都会被收集进Vec<ScenarioError>:
- 删除 DB 实例:
DeleteDbInstance(使用skip_final_snapshot(true)),随后轮询DescribeDbInstances,直到该集群下不再有实例或状态离开Deleting; - 删除 DB 集群:
DeleteDbCluster(同样skip_final_snapshot(true)),随后轮询DescribeDbClusters,直到集群列表为空; - 删除 DB 集群参数组:
DeleteDbClusterParameterGroup。
main中所有阶段产生的告警统一收集到Warnings结构并最终汇总打印;若任何一步失败,进程以非零状态退出(见 aurora-scenario.rs)。
底层封装层:rds.rs 中的全部 API 动作
src/rds.rs 将所有aws_sdk_rds调用收敛到一个RdsImpl结构(持有RdsClient),每个方法都用// snippet-start:[rust.aurora.xxx.wrapper]标注,便于文档自动抽取。README 的 "Single actions" 清单与其一一对应:
| API 动作 | 封装方法 | 位置 |
|---|---|---|
DescribeDBEngineVersions | describe_db_engine_versions(engine) | rds.rs |
DescribeOrderableDBInstanceOptions | describe_orderable_db_instance_options(engine, engine_version),分页收集 | rds.rs |
CreateDBClusterParameterGroup | create_db_cluster_parameter_group(name, description, family) | rds.rs |
DescribeDBClusters | describe_db_clusters(id) | rds.rs |
DescribeDBClusterParameters | describe_db_cluster_parameters(name),分页收集 | rds.rs |
ModifyDBClusterParameterGroup | modify_db_cluster_parameter_group(name, parameters) | rds.rs |
CreateDBCluster | create_db_cluster(name, parameter_group, engine, version, username, password) | rds.rs |
CreateDBInstance | create_db_instance(cluster_name, instance_name, instance_class, engine) | rds.rs |
DescribeDBInstances(单实例) | describe_db_instance(instance_identifier) | rds.rs |
CreateDBClusterSnapshot | snapshot_cluster(db_cluster_identifier, snapshot_name) | rds.rs |
DescribeDBInstances(全量) | describe_db_instances() | rds.rs |
DescribeDBClusterEndpoints | describe_db_cluster_endpoints(cluster_identifier) | rds.rs |
DeleteDBInstance | delete_db_instance(instance_identifier),skip_final_snapshot(true) | rds.rs |
DeleteDBCluster | delete_db_cluster(cluster_identifier),skip_final_snapshot(true) | rds.rs |
DeleteDBClusterParameterGroup | delete_db_cluster_parameter_group(name) | rds.rs |
几个值得注意的实现细节:
- 密码处理:
create_db_cluster接收SecretString,仅在发送请求时通过password.expose_secret()取出明文,避免密码长时间驻留在普通字符串中; - 分页器复用:
describe_orderable_db_instance_options与describe_db_cluster_parameters都使用into_paginator().send().try_collect(),一次性拉取全部结果,省去手动翻页代码; - 删除均跳过最终快照:
delete_db_instance与delete_db_cluster都显式设置skip_final_snapshot(true),确保清理流程不会因额外快照而拖慢或残留资源。
测试与验证:mockall 驱动的单元测试
Aurora 示例 README 明确提示运行测试可能产生 AWS 账户费用,但这里说的"测试"主要指集成测试;而仓库中的单元测试不会产生费用。rds.rs中通过条件编译接入 mock:
#[cfg(test)] use mockall::automock; #[cfg(test)] pub use MockRdsImpl as Rds; #[cfg(not(test))] pub use RdsImpl as Rds;即测试编译时用MockRdsImpl替换真实的RdsImpl。全部单元测试位于 src/aurora_scenario/tests.rs,覆盖场景的每一条成功与失败路径,例如:
test_scenario_set_engine/test_scenario_set_engine_param_group_exists:验证创建参数组的参数匹配与DBParameterGroupAlreadyExists错误处理;test_scenario_get_engines:验证引擎族到版本列表的映射组装,mock 返回f1/f2两个族并断言输出;test_scenario_get_instance_classes:验证仅保留storage_type == "aurora"的实例规格(mock 中aurora-iopt1被过滤掉);test_scenario_update_auto_increment:断言ModifyDbClusterParameterGroup收到的参数列表与ApplyMethod::Immediate完全一致(offset=10、increment=20);test_scenario_connection_string:断言拼出的连接串为mysql -h test_endpoint -P 3306 -u test_username -p;test_start_cluster_and_instance:使用tokio::time::pause()/advance()虚拟时钟推进等待循环,模拟集群与实例进入可用状态;test_scenario_clean_up/test_scenario_clean_up_errors:验证按"实例→集群→参数组"顺序删除,以及删除失败时错误被收集为Vec<ScenarioError>;test_scenario_snapshot:验证快照标识符拼接格式{cluster}_{name}。
运行单元测试:
cargo test按 rustv1/README.md 的说明,单元测试不会对 AWS 账号造成任何变更或费用;集成测试(可能产生费用)可通过cargo test -- --ignored单独运行。
运行示例的完整命令汇总
| 目的 | 命令 |
|---|---|
| 快速查看现有集群(Hello Aurora) | cargo run --bin hello-world |
| 运行完整集群生命周期场景 | cargo run --bin aurora-scenario |
| 运行单元测试(无费用) | cargo test |
| 运行集成测试(可能产生费用) | cargo test -- --ignored |
场景运行全程交互,注意密码必须不少于 8 个字符;由于集群创建最长可能耗时 20 分钟,请为等待阶段预留足够时间。
注意事项与最佳实践
- 费用:创建 Aurora 集群、实例、快照以及运行相关测试都会产生 AWS 账户费用,建议在明确了解计费规则的前提下运行,并在演示结束后确保
clean_up执行成功,避免残留资源持续计费; - 最小权限:建议按最小权限原则授予运行代码所需的 IAM 权限,仅开放
rds:Describe*、rds:Create*、rds:Modify*、rds:Delete*中必要的动作; - 区域可用性:本示例代码未在每个 AWS 区域实测,部分区域可能不提供 Aurora 或特定引擎版本,请以所选区域的实际支持情况为准;
- 重入安全:场景为参数组创建设计了幂等逻辑(已存在则跳过),但重复运行时若集群/实例仍存在,
CreateDBCluster与CreateDBInstance可能返回已存在错误,此时需先清理上一次运行残留; - 参数组语义:
auto_increment_offset与auto_increment_increment属于 MySQL 的自增步进与起始偏移参数,在 Aurora 集群参数组中修改后仅对新建立的连接生效,示例选择ApplyMethod::Immediate以演示立即生效的用法。
延伸阅读指引
- 总览:
rustv1目录下的 README.md 说明了整个 Rust 示例代码库的布局、环境变量与运行约定; - 场景编排:src/aurora_scenario/mod.rs 与可执行入口 src/bin/aurora-scenario.rs;
- API 封装:src/rds.rs;
- 测试用例:src/aurora_scenario/tests.rs;
- 轮询工具:
sdk-examples-test-utils的Waiter实现位于 rustv1/test-utils。
如需进一步了解 Aurora 的架构与 API 细节,可查阅 AWS 官方的 Aurora 用户指南、Aurora API 参考以及 SDK for Rust 的 Aurora 参考文档(aws-sdk-aurora/aws-sdk-rdscrate 文档)。
- 示例工程
- 教程
- 后端
【免费下载链接】aws-doc-sdk-examples
Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.
相关推荐
使用 AWS SDK for Rust 操作 Amazon EC2:从 Hello World 到完整实例生命周期管理
使用 AWS SDK for Rust 操作 Amazon EC2:从 Hello World 到完整实例生命周期管理 本文基于 AWS Code Exampl
示例工程教程后端使用 AWS SDK for C++ 操作 Amazon RDS:从 Hello World 到 DB 实例全生命周期管理
使用 AWS SDK for C++ 操作 Amazon RDS:从 Hello World 到 DB 实例全生命周期管理 本文基于 cpp/example_c
示例工程教程后端使用 AWS SDK for Kotlin 管理 Amazon EC2:从 Hello World 到完整实例生命周期场景
使用 AWS SDK for Kotlin 管理 Amazon EC2:从 Hello World 到完整实例生命周期场景 本文基于 aws doc sdk e
示例工程教程后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考