1 个不稳定版本
0.3.0-patched.1 | 2021 年 5 月 20 日 |
---|
#553 在 HTTP 服务器
在 2 个 Crates 中使用 (通过 tide-lambda-listener)
115KB
2.5K SLoC
Rust Runtime for AWS Lambda
此包简化了用 Rust 编写的 AWS Lambda 函数的运行。此工作区包括多个 Crates
-
lambda-runtime
是一个库,为用 Rust 编写的应用程序提供 Lambda 运行时。 -
lambda-http
是一个库,使您能够轻松地在 Rust 中编写以 API Gateway 代理事件为重点的 Lambda 函数。
示例函数
下面的代码创建了一个简单的函数,它接收一个包含 firstName
字段的事件,并向调用者返回一条消息。注意:此 crate 对最新稳定版本的 Rust 进行了测试。
use lambda_runtime::{handler_fn, Context, Error};
use serde_json::{json, Value};
#[tokio::main]
async fn main() -> Result<(), Error> {
let func = handler_fn(func);
lambda_runtime::run(func).await?;
Ok(())
}
async fn func(event: Value, _: Context) -> Result<Value, Error> {
let first_name = event["firstName"].as_str().unwrap_or("world");
Ok(json!({ "message": format!("Hello, {}!", first_name) }))
}
上面的代码与 lambda_runtime
crate 中的 基本示例 相同。
部署
目前有几种构建此包的方法:手动使用 AWS CLI 和使用 Serverless 框架。
AWS CLI
要使用 AWS CLI 将基本示例作为 Lambda 函数部署,我们首先需要使用 cargo
手动构建它。由于 Lambda 使用 Amazon Linux,您需要为目标可执行文件指定 x86_64-unknown-linux-musl
平台。
运行此脚本一次以添加新目标
$ rustup target add x86_64-unknown-linux-musl
- 注意:如果您正在运行 Mac OS,则需要为目标平台安装链接器。您可以使用来自 Homebrew 的
musl-cross
tap 来执行此操作,它为 Mac OS 提供了一个完整的交叉编译工具链。一旦安装了musl-cross
,我们还需要在构建x86_64-unknown-linux-musl
平台时通知 cargo 新安装的链接器。
$ brew install filosottile/musl-cross/musl-cross
$ mkdir .cargo
$ echo $'[target.x86_64-unknown-linux-musl]\nlinker = "x86_64-linux-musl-gcc"' > .cargo/config
编译示例之一,将其编译为 发布 版本,以便部署到 AWS
$ cargo build -p lambda_runtime --example basic --release --target x86_64-unknown-linux-musl
对于 自定义运行时,AWS Lambda 会在部署包 zip 中查找名为 bootstrap
的可执行文件。将生成的 basic
可执行文件重命名为 bootstrap
并将其添加到 zip 归档中。
$ cp ./target/x86_64-unknown-linux-musl/release/examples/hello ./bootstrap && zip lambda.zip bootstrap && rm bootstrap
现在我们有了部署包(lambda.zip
),我们可以使用 AWS CLI 创建一个新的 Lambda 函数。请确保用您账户中现有的角色替换执行角色!
$ aws lambda create-function --function-name rustTest \
--handler doesnt.matter \
--zip-file fileb://./lambda.zip \
--runtime provided \
--role arn:aws:iam::XXXXXXXXXXXXX:role/your_lambda_execution_role \
--environment Variables={RUST_BACKTRACE=1} \
--tracing-config Mode=Active
您现在可以使用 AWS CLI 或 AWS Lambda 控制台测试该函数
$ aws lambda invoke --function-name rustTest \
--payload '{"firstName": "world"}' \
output.json
$ cat output.json # Prints: {"message": "Hello, world!"}
注意:使用 AWS CLI 版本 2 时,--cli-binary-format raw-in-base64-out
是必选参数。更多信息
Serverless Framework
或者,您可以使用 Serverless framework Rust 插件 声明性地构建基于 Rust 的 Lambda 函数。
存在许多入门 Serverless 应用程序模板,可以帮助您快速启动
- 一个最小的 echo 函数,演示最小的 Rust 函数设置是什么样的
- 一个最小的 http 函数,演示如何使用 Rust 的原生 http 包与 API Gateway 交互(注意这将是 git 依赖项,直到 0.2 发布)
- 一个组合 multi 函数服务,演示如何设置具有多个独立函数的服务
假设您的宿主机具有相对较新的 node 版本,您 不需要安装任何全局 serverless 依赖项。要开始,请运行以下命令以创建一个新的 lambda Rust 应用程序并安装项目级依赖项。
$ npx serverless install \
--url https://github.com/softprops/serverless-aws-rust \
--name my-new-app \
&& cd my-new-app \
&& npm install --silent
使用标准 serverless 工作流程部署它
# build, package, and deploy service to aws lambda
$ npx serverless deploy
使用 serverless framework 或配置的 AWS 集成触发源调用它
$ npx serverless invoke -f hello -d '{"foo":"bar"}'
Docker
或者,您可以在 AWS Lambda 提供的运行时 docker 映射中构建基于 Rust 的 Lambda 函数,预安装 Rust 工具链。
运行以下命令将启动一个临时的 docker 容器,该容器将构建您的 Rust 应用程序并生成一个 zip 文件,其中包含其二进制文件自动重命名为 bootstrap
,以满足 AWS Lambda 对二进制文件的要求,通常这仅是您的 crate 名称,如果您使用的是 cargo 默认二进制(即 main.rs
)
# build and package deploy-ready artifact
$ docker run --rm \
-v ${PWD}:/code \
-v ${HOME}/.cargo/registry:/root/.cargo/registry \
-v ${HOME}/.cargo/git:/root/.cargo/git \
softprops/lambda-rust
当您的应用程序构建并打包后,即可部署到生产环境。您还可以使用lambdaci:提供的Docker容器本地调用它来验证其行为,该容器也是AWS Lambda提供的运行时镜像,其中省略了构建依赖项。
# start a docker container replicating the "provided" lambda runtime
# awaiting an event to be provided via stdin
$ unzip -o \
target/lambda/release/{your-binary-name}.zip \
-d /tmp/lambda && \
docker run \
-i -e DOCKER_LAMBDA_USE_STDIN=1 \
--rm \
-v /tmp/lambda:/var/task \
lambci/lambda:provided
# provide an event payload via stdin (typically a json blob)
# Ctrl-D to yield control back to your function
调试
Lambda函数可以在本地运行和调试,使用一个特殊的Lambda调试代理(由@rimutaka维护的非AWS仓库),这是一个Lambda函数,它将传入的请求转发到一个AWS SQS队列,并从另一个队列读取响应。运行在您开发计算机上的本地代理读取队列,调用您的Lambda函数并返回响应。这种方法允许在AWS工作流程中本地调试Lambda函数,而无需修改本地和AWS版本之间的lambda处理程序代码。
lambda
lambda_runtime
是一个用于编写可靠和性能优良的基于Rust的AWS Lambda函数的库。从高层次来看,它提供了一些主要组件
Handler
,一个定义客户编写的代码与该库之间交互的特质。lambda_runtime::run
,运行Handler
的函数。
函数handler_fn
将Rust函数或闭包转换为Handler
,然后可以由lambda_runtime::run
运行。
AWS事件对象
该项目目前不包括Lambda事件结构定义,尽管我们计划在未来这样做。相反,可以使用社区维护的aws_lambda_events
crate来利用提供强类型Lambda事件结构。您也可以创建自己的自定义事件对象及其对应的结构。
自定义事件对象
为了序列化和反序列化事件和响应,我们建议使用serde
库。为了接收自定义事件,使用Serde的宏注解您的结构
use serde::{Serialize, Deserialize};
use serde_json::json;
use std::error::Error;
#[derive(Serialize, Deserialize)]
pub struct NewIceCreamEvent {
pub flavors: Vec<String>,
}
#[derive(Serialize, Deserialize)]
pub struct NewIceCreamResponse {
pub flavors_added_count: usize,
}
fn main() -> Result<(), Box<Error>> {
let flavors = json!({
"flavors": [
"Nocciola",
"抹茶",
"आम"
]
});
let event: NewIceCreamEvent = serde_json::from_value(flavors)?;
let response = NewIceCreamResponse {
flavors_added_count: event.flavors.len(),
};
serde_json::to_string(&response)?;
Ok(())
}
依赖项
~6.5–9MB
~155K SLoC