#aws-lambda #lambda #aws #serverless #http #http-interface

lando-attr

Rust http 接口用于 AWS lambda API 网关事件(attr 宏)

2 个版本

使用旧的 Rust 2015

0.2.1 2018年11月28日
0.2.0 2018年11月28日

#25#http-interface

21 每月下载次数
lando 中使用

MIT 许可证

5KB

构建状态 覆盖率状态 crates.io docs.rs Master API 文档

使用 RustlangAWS Lambda 上运行 http 应用程序,使用 API Gateway

#[macro_use] extern crate lando;

gateway!(|_, _| {
  Ok("👋 Hello, what have we here?")
});

🤔 关于

Lando 是一个用于构建 无服务器 Rustlang HTTP 应用的 crate。

Rust 生态系统有一些非常优秀的 HTTP 服务器 crate。它们大多数捆绑了服务器,这些服务器解析 HTTP 消息,监听端口并管理网络连接,并将托管、扩展、监控和操作的责任留给你,除了你的应用程序代码之外。

Lando 不同。Lando 的唯一重点是编写 应用程序。它将管理服务器的 无差别的繁重工作 和责任转移给 AWS。更直接地说,AWS lambda 释放了您运行代码而无需考虑服务器的负担。

Lando 采用 Rust 社区的 http crate 作为其核心接口,用于 API Gateway。Lando 扩展了 crowbar crate 的工作,该 crate 提供了用 lambda 的 最低开销运行时,Python 3.6 部署 Rust 应用程序所需的底层机制。Lando 针对由 API Gateway 触发的 lambda。如果您正在为 Lambda 的 许多其他触发器 构建应用程序,请检查 crowbar

存在一个庞大且成熟的AWS Lambda工具生态系统,并且运行良好,包括如无服务器工具包之类的流程工具。由于这些工具很可能已经在组织中存在,引入Rustlang的门槛将会大大降低。Lando并不打算取代这些工具,而是与之良好协作。

👍 Rust成为Lambda应用程序的良好选择的原因

AWS Lambda的定价模型主要基于两个因素:内存大小和速度。分配给应用程序的CPU与请求的内存大小成比例。Lambda采用按使用付费的定价模型,有利于快速且内存开销低的程序。

作为一种系统语言,Rust专为这些需求设计。Rust拥有一个非常小巧的运行时,非常高效地管理内存,并且非常快速

作为一种高度可嵌入的语言,它对如Python的运行时互操作性故事是💖。请注意,Lando假设您通过AWS API网关公开这些应用程序,它有自己的慷慨的定价模型

📦 安装

将以下内容添加到您的Cargo项目中的Cargo.toml文件。

[lib]
crate-type = ["cdylib"]

[dependencies]
lando = "0.2"

💡 crate-type属性链接并生成一个共享对象(*.so)文件,允许您的Rustlang应用程序编译为Linux原生二进制文件,可以从AWS Python 3.6 Lambda运行时调用。

👩‍🏭 创建

Lando导出了一个名为gateway!的宏,该宏又导出一个Rust函数或闭包到Cpython原生二进制扩展,使其可以用于AWS Lambda。

#[macro_use] extern crate lando;

gateway!(|request, _context| {
  println!("{:?}", request);
  Ok("hello lambda")
});

此闭包接受一个包含lando::Bodyhttp::Request。如果需要,此Body类型可以被解引用为字节数组。

有关更多详细信息,请参阅此项目的crate文档

Lando还支持将函数作为Lambda准备好的函数导出的属性方法。

#[macro_use] extern crate lando;
use lando::{Request, LambdaContext, IntoResponse, Result};

#[lando]
fn example(
  _: Request,
  _: LambdaContext
) -> Result<impl IntoResponse> {
   Ok("hello lambda")
}

🔬 测试

由于这些函数只是Rust,您可以使用内置的单元测试框架测试您的应用程序

此外,您还可以通过本地调用它们来集成测试您的函数

🐳 Lambda CI

Lambda CI Docker项目包含镜像,这些镜像反映了AWS Lambda运行时。这使得您可以在与AWS相匹配的本地环境中构建和测试您的Lambda项目。

构建

要在Lambda兼容的环境中调用您的函数,您必须首先在其中一个环境中构建它。

$ docker run --rm \
  -v ${PWD}:/code \
  -v ${HOME}/.cargo/registry:/root/.cargo/registry \
  -v ${HOME}/.cargo/git:/root/.cargo/git \
  -e CARGO_FLAGS="--features lando/python3-sys" \
  softprops/lambda-rust

这将在target/lambda/release目录下生成一个原生Linux二进制文件.so

调用

您可以使用lambci/lambda:python3.6 Docker镜像在本地调用您的Lambda。

本示例通过管道传递文件来通过标准输入提供lambda的事件,在这个例子中是一个名为example_request.json的文件。请随意创建您自己的模拟输入。

cat example_request.json
{
  "path": "/test/hello",
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "Accept-Encoding": "gzip, deflate, lzma, sdch, br",
    "Accept-Language": "en-US,en;q=0.8",
    "CloudFront-Forwarded-Proto": "https",
    "CloudFront-Is-Desktop-Viewer": "true",
    "CloudFront-Is-Mobile-Viewer": "false",
    "CloudFront-Is-SmartTV-Viewer": "false",
    "CloudFront-Is-Tablet-Viewer": "false",
    "CloudFront-Viewer-Country": "US",
    "Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com",
    "Upgrade-Insecure-Requests": "1",
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48",
    "Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)",
    "X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==",
    "X-Forwarded-For": "192.168.100.1, 192.168.1.1",
    "X-Forwarded-Port": "443",
    "X-Forwarded-Proto": "https"
  },
  "pathParameters": {
    "proxy": "hello"
  },
  "requestContext": {
    "accountId": "123456789012",
    "resourceId": "us4z18",
    "stage": "test",
    "requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9",
    "identity": {
      "cognitoIdentityPoolId": "",
      "accountId": "",
      "cognitoIdentityId": "",
      "caller": "",
      "apiKey": "",
      "sourceIp": "192.168.100.1",
      "cognitoAuthenticationType": "",
      "cognitoAuthenticationProvider": "",
      "userArn": "",
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48",
      "user": ""
    },
    "resourcePath": "/{proxy+}",
    "httpMethod": "GET",
    "apiId": "wt6mne2s9k"
  },
  "resource": "/{proxy+}",
  "httpMethod": "GET",
  "queryStringParameters": {
    "name": "me"
  },
  "stageVariables": {
    "stageVarName": "stageVarValue"
  }
}

使用docker调用生成的函数,将模拟事件的上下文作为stdin提供。

$ docker run \
  -i -e DOCKER_LAMBDA_USE_STDIN=1 \
  --rm \
  -v \
  "$PWD/target/lambda/release":/var/task lambci/lambda:python3.6 \
  liblambda.handler < example_request.json

🚀 部署

为了部署您的应用程序,您需要在与lambda Python 3.6环境兼容的运行时中构建它。

⚡ 无服务器框架

开始推荐的方式是使用无服务器框架。存在一个无服务器框架插件,用于加速开发/部署周期。

您可以使用这个无服务器项目模板来启动一个新的、准备部署的lando应用程序。

$ serverless install \
  --url https://github.com/softprops/serverless-lando \
  --name my-new-service

🐳 Docker

为了方便,提供了一个Docker镜像,它复制了AWS Python3.6环境,并带有Rustlang构建工具。

它专注于针对Rust的稳定版本的应用程序。

$ docker run --rm \
  -v ${PWD}:/code \
  -v ${HOME}/.cargo/registry:/root/.cargo/registry \
  -v ${HOME}/.cargo/git:/root/.cargo/git \
  -e CARGO_FLAGS="--features lando/python3-sys" \
  softprops/lambda-rust

这将在target/lambda目录下生成可部署的.so构建工件。

然后可以将其压缩以供AWS lambda部署。

🏃 性能

lambda应用程序或任何应用程序的性能分析取决于您的用例。在lando的具体情况下,因素包括

  • 您使用api gateway(AWS运行的HTTP负载均衡器,调用您的函数)
  • 您的lambda配置(内存分配以及连接到VPC等资源)
  • lambda翻译层(在Python和Rust之间进行转换)
  • 您的应用程序(那是指您!)

无服务器思维模式是明确以运行时控制为代价,专注于应用程序。

您的应用程序能够以十毫秒双位数运行。

Lando的目标是在原生Python事件和原生Rustlang http类型之间提供最少侵入性的翻译层

存在一个基准测试来测量典型的网关事件的转换时间,报告的结果为典型(8.65 μ(微)秒结果 +/- 4 μ秒)。这不太可能成为您应用程序的瓶颈

test gateway_conversion ... bench:       8,652 ns/iter (+/- 4,193)

💱 并发性

在AWS Lambda中追求性能时应考虑并发性。

AWS Lambda明确是水平扩展的。您不是通过在运行进程(向上扩展 ↕️)中生成更多线程来扩展,而是通过生成更多lambda(向外扩展 ↔️)来扩展。

AWS Lambda的一个关键优势是平台通过为您生成更多函数实例来处理并发性。这导致了一些经济优势,因为您只需为使用的部分付费。请注意,您按100毫秒的间隔计费,因此一旦低于这个点,优化成本的有用性就丧失了

野外的例子

  • slack standup 自动化standups的slack命令webhook
  • jirabars 基于分支名称填充jira占位符信息的github webhook
  • barbershop 在pr后删除分支的github webhook

🚧 计划中的更改

(无)

Doug Tangren (softprops) 2018

依赖项

~2MB
~46K SLoC