#aws-lambda #api-gateway #lambda #aws #load-balancing #alb

netlify_lambda_http

AWS Lambda的应用负载均衡器和API网关事件类型

4个版本

0.2.0 2021年1月7日
0.1.2 2020年12月16日
0.1.1 2020年12月7日
0.1.0 2020年12月4日

网络编程 中排名第1878

Download history 27/week @ 2024-01-04 45/week @ 2024-01-11 44/week @ 2024-01-18 22/week @ 2024-01-25 11/week @ 2024-02-01 31/week @ 2024-02-08 54/week @ 2024-02-15 55/week @ 2024-02-22 57/week @ 2024-02-29 73/week @ 2024-03-07 63/week @ 2024-03-14 59/week @ 2024-03-21 77/week @ 2024-03-28 84/week @ 2024-04-04 62/week @ 2024-04-11 48/week @ 2024-04-18

每月下载量278
3 个crate 中使用

Apache-2.0

90KB
1.5K SLoC

Rust AWS Lambda运行时

此包使您能够轻松运行用Rust编写的AWS Lambda函数。

⚠️ ⚠️ ⚠️ 👷 👷 👷 🍴 🍴 🍴

这是AWS Lambda官方Rust运行时的一个分支。我们创建这个分支是为了能够推进社区在awslabs仓库中停滞的贡献,因为没有发布。

此仓库中的crate以前缀netlify-发布到crates.io。

Netlify Lambda 包含运行时组件。 Netlify Lambda Attributes 包含创建Lambda函数的定义。 Netlify Lambda HTTP 包含通过HTTP端点访问Lambda函数的定义。

⚠️ ⚠️ ⚠️ 👷 👷 👷 🍴 🍴 🍴

示例函数

下面的代码创建了一个简单的函数,该函数接收包含firstName字段的事件,并返回一个消息给调用者。注意:此crate针对最新的稳定Rust进行测试。

use netlify_lambda::{handler_fn, Context};
use serde_json::{json, Value};

type Error = Box<dyn std::error::Error + Send + Sync + 'static>;

#[tokio::main]
async fn main() -> Result<(), Error> {
    let func = handler_fn(func);
    netlify_lambda::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 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 --example hello --release --target x86_64-unknown-linux-musl

对于自定义运行时,AWS Lambda会在部署包zip中查找名为bootstrap的可执行文件。将生成的basic可执行文件重命名为bootstrap并将其添加到zip归档中。

$ cp ./target/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!"}

注意:--cli-binary-format raw-in-base64-out是使用AWS CLI版本2时必需的参数。更多信息

Serverless框架

或者,您可以使用Serverless框架Rust插件声明性地构建基于Rust的Lambda函数。

存在许多入门级Serverless应用程序模板,可以帮助您快速启动。

  • 一个最小的echo函数,以展示最小的Rust函数设置是什么样的
  • 一个最小的http函数,以展示如何使用Rust的本地http crate与API Gateway接口(请注意,这将是git依赖项,直到0.2发布)
  • 一个组合多功能服务,以展示如何设置具有多个独立函数的服务

假设您的宿主机有相对较新的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框架或配置的AWS集成触发源调用它

$ npx serverless invoke -f hello -d '{"foo":"bar"}'

Docker

或者,您可以在预安装了Rust工具链的AWS Lambda提供运行时的Docker镜像中构建基于Rust的Lambda函数。

运行以下命令将启动一个临时的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是一个用于编写可靠和高效的基于 Rust 的 AWS Lambda 函数的库。从高层次来看,它提供了一些主要组件:

  • Handler,一个定义客户编写的代码与该库之间交互的特质。
  • netlify_lambda::run,一个运行 Handler 的函数。

函数 handler_fn 将 Rust 函数或闭包转换为 Handler,然后可以被 netlify_lambda::run 执行。

自定义事件对象

为了序列化和反序列化事件和响应,我们建议使用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(())
}

依赖项

~9–20MB
~265K SLoC