动手 lambda 新功能,custom runtime

阅读数:65 2019 年 10 月 12 日 14:26

动手 lambda 新功能,custom runtime

什么是 lambda custom runtime

背景

lambda 原来只能支持有限的语言种类,包括 node.js, python, .Net, Go, java, ruby 等。

如果需要在 Lambda 上运行不支持的语言或者二进制文件该怎么办呢?原先有一种比较有趣的方案,其实就是用已经支持的语言来写一个代理,包装在不被支持的语言的二进制运行文件之上。(参考 在 lambda 上运行其他语言)

而 lambda custom runtime 就是正统的这个问题的解决方案。

AWS 新出的官方对于 c++ 和 rust 的支持其实都是基于 custom runtime 来实现的,底层都使用了 runtime API 技术。

  • rust runtime
  • cpp runtime

什么是 runtime API

runtime API 是 aws lambda 所提供的 http API, 帮助 custom runtime 监听 lambda 的触发事件,和返回处理结果。

runtime API 一共有 4 个 API 接口:

触发事件监听
HTTP 请求类型: GET

HTTP 请求路径: /runtime/invocation/next

curl “ http://$ {AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next”
返回正常处理结果
HTTP 请求类型: POST

HTTP 请求路径: /runtime/invocation/AwsRequestId/response

复制代码
REQUEST_ID=156cb537-e2d4-11e8-9b34-d36013741fb9
curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "SUCCESS"

返回处理异常

HTTP 请求类型: POST

HTTP 请求路径: /runtime/invocation/AwsRequestId/error

复制代码
REQUEST_ID=156cb537-e2d4-11e8-9b34-d36013741fb9
ERROR="{\"errorMessage\" : \"Error parsing event data.\", \"errorType\" : \"InvalidEventDataException\"}"
curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/error" -d "$ERROR"

返回初始化错误

HTTP 请求类型: POST

HTTP 请求路径: /runtime/init/error

复制代码
REQUEST_ID=156cb537-e2d4-11e8-9b34-d36013741fb9
ERROR="{\"errorMessage\" : \"Failed to load function.\", \"errorType\" : \"InvalidFunctionException\"}"
curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/init/error" -d "$ERROR"

runtime API 的使用

runtime API 的使用流程一般是:

1. 循环监听触发事件监听 API
2. 对每次事件,使用相对应自定义代码处理
3. 根据处理的成功和失败,使用相对应的返回 API 返回结果
4. 将以上这些逻辑打包成为一个 bootstrap 可执行文件,上传到 lambda
接下来的小实验会帮助大家动手理解 runtime API 的使用方式,大家也可以之后参考 rust runtime 的实现方式

小实验

1. 用 custom runtime 跑 bash 脚本
2. 用 layer 分离 runtime 和 lambda 方法
3. 用 custom runtime 跑 php 脚本

用 custom runtime 跑 bash 脚本

这个小实验当中,我们参考官方教程创建一个 bash 的 custom runtime,实现简单的直接 echo 返回事件输入数据的功能。

1. 创建 bootstrap 和 function 代码
bootstrap

复制代码
#!/bin/sh
set -euo pipefail
# Initialization - load function handler
source $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh"
# Processing
while true
do
HEADERS="$(mktemp)"
# Get an event
EVENT_DATA=$(curl -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
# Execute the handler function from the script
RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA")
# Send the response
curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE"
done
function.sh
function handler () {
EVENT_DATA=$1
echo "$EVENT_DATA" 1>&2;
RESPONSE="Echoing request: '$EVENT_DATA'"
echo $RESPONSE
}

打包 bootstrap 和 function.sh 到一个 zip 文件。
注意: bootstrap 和 function.sh 都需要配置成为可执行文件, 大家也可以直接使用我已经打包好的 zip

3. 在控制台创建 lambda 并上传 zip 文件
创建 lambda

动手 lambda 新功能,custom runtime

上载 zip 包

动手 lambda 新功能,custom runtime
创建测试案例并测试
动手 lambda 新功能,custom runtime

测试
动手 lambda 新功能,custom runtime

用 layer 分离 runtime 和 lambda 方法
这个小实验中,我们在实验 1 的基础上面把 bash 的 custom runtime 分离到 lambda layer(什么是 layer?) 上去。

因为 layer 是可以和多个 lambda 分享的,所以以后我们要写一个 bash 的 lamda 程序,只需要写一下自己的 function.sh ,然后再在该 lambda 上加入 bash custom runtime layer 就可以直接工作了!

1. 创建 lambda
和实验一中的步骤一样创建 lambda, 唯一的区别在于上载的 zip 包中现在只包含 funtion.sh

大家可以直接使用我已经打包好的 function_only.zip

2. 打包 layer 代码
单独打包 bootstrap 代码到 runtime.zip 大家可以直接使用我已经打包好的 runtime.zip

3. 创建 layer

动手 lambda 新功能,custom runtime
记录下 layer 的 ARN

动手 lambda 新功能,custom runtime

添加 layer 到 lambda
动手 lambda 新功能,custom runtime

注意:添加过程中请选择“提供层版本 ARN”, 并填写刚才记录下的 layer 的 ARN

动手 lambda 新功能,custom runtime
5. 测试
和实验一中的测试步骤和结果相同

用 custom runtime 跑 php 脚本

在本实验当中,我们借用 stackery 分享的 php custom runtime 来跑 PHP 的脚本, 实现简单的 hello world 功能。

1. 创建 lambda
创建 index.php 代码

复制代码
Hello World! You've reached <?php print($_SERVER['REQUEST_URI']); ?>

如实验 1,2 一样创建 lambda,打包 index.php,并上传。 大家可以直接使用我打包好的 function_php.zip

注意:处理程序项要填写成 index.php

添加 php custom 层
如实验 2 中一样在 lambda 上添加层。

大家可以直接使用我分享在中国北京区的 php 层。(arn:aws-cn:lambda:cn-north-1:074481125102:layer:stackery_php:1)
动手 lambda 新功能,custom runtime

也可以自己如实验 2 一样创建新的 php custom 层。

关于创建 php custom 层时所需要使用的 zip 包,大家可以根据 stackery 文档编译 custom runtime, 或直接下载我打包编译好的 php71.zip

3. 创建测试案例并测试
创建测试案例,选择 API gateway lambda proxy 模板。 注意:我们现在使用的 stackery php 层,默认识别的请求格式为 API gateway lambda proxy 格式。如果格式不同,需要修改配置或者 runtime 代码。

动手 lambda 新功能,custom runtime

测试结果

动手 lambda 新功能,custom runtime

后话
custom runtime 通过 runtime API 的形式让 lambda 有了无限的可能性。什么是以前 lambda 不能做,现在却能做的事情呢?欢迎大家发挥想象,一起玩起来!

相关文章:
runtime api: https://docs.aws.amazon.com/zh_cn/lambda/latest/dg/runtimes-api.html
创建 custom runtime 官方教程: https://docs.aws.amazon.com/zh_cn/lambda/latest/dg/runtimes-walkthrough.html

作者介绍:

任庆杰
AWS 解决方案架构师,无服务器专家。负责基于 AWS 的云计算方案架构的咨询和设计,同时致力于 AWS 云服务在国内和全球的应用和推广。在加入 AWS 前,拥有超过 7 年的软件开发和 IT 项目管理经验。

本文转载自 AWS 技术博客。

原文链接:
https://amazonaws-china.com/cn/blogs/china/lambda-new-function-custom-runtime/

欲了解 AWS 的更多信息,请访问【AWS 技术专区】

评论

发布