写点什么

适用于 AWS Lambda 的 Dart 运行时简介

  • 2020-02-27
  • 本文字数:5331 字

    阅读完需:约 17 分钟

适用于 AWS Lambda 的 Dart 运行时简介

Dart 是一种发展迅速的开源编程语言,并且能为一些快速发展的开源项目提供支持,如 Flutter。借助自定义 AWS Lambda 运行时,您可以在 AWS Lambda 中运行 Dart。以 Dart 编写函数有助于让您使用自己的技能开发移动应用程序,从而建立无服务器后端。您也可以在应用程序和后端之间共享代码,并且使用静态类型语言的强大功能。本篇博文将阐释我们如何通过自定义 Lambda 运行时来提供语言支持,以及如何以 Dart 创建 Lambda 函数。文章还将分享一些诀窍,在您的构建过程中助您一臂之力。

什么是 Dart?

Dart 是一种热门的开源编程语言,它以对象为导向,是通用型编程语言。Dart 可用于编写命令行脚本、移动应用程序、Web 应用程序或服务器端应用程序。这是一种静态类型语言,具有可靠的类型系统,并且配备功能强大的包管理器和开发人员工具。


这种语言是 2018-2019 年发展最迅速的语言之一,这并不让人感到意外,因为最热门的 Flutter 移动开发工具包正是使用 Dart 编写。此开发工具包是 GitHub 上最为流行的开源项目之一。深入研究之前,您可以先访问 Dart 网站了解这种语言及其功能,并使用 DartPad 对它进行实验。

Dart 和 AWS Lambda 自定义运行时

利用自定义 AWS Lambda 运行时,您可以在任何编程语言中执行运行时。自定义 Lambda 运行时会在运行的时候使用 AWS Lambda 运行时界面。它定义了基于 HTTP 的 Lambda 编程模型规范,自定义运行时使用此规范来处理调用请求。借助 AWS Lambda 自定义运行时,您还可以利用最近发布的 Dart 编程语言运行时,在 Lambda 中执行 Dart。借助我们的运行时,您也可以用 Dart 来进行无服务器计算。

入门

在下面的步骤中,我们将使用 Dart 自定义运行时来设置 Lambda 函数,然后对其进行配置以通过事件源接收请求,对此,我们以 Application Load Balancer 为例。此项目将向请求者返回简单的消息。


对于目标为设备(移动、桌面或服务器)的程序,Dart 支持 Dart VM 使用适时 (JIT) 编译和预先 (AOT) 编译器来生成各自的机器代码。对于目标为 Web 的程序,Dart 提供 Dart to JavaScript 编译器。AWS Lambda 是服务器设备目标,并且运行时项目使用 AOT 编译器来为目标生成机器代码。


Dart 2.6 推出了 dart2native 命令行工具,可更轻松生成本机机器代码。此工具还可将 Dart 程序编译为所需的本机 x64 机器代码,此外还有小型 Dart 运行时,可处理类型检查和垃圾收集。运行时项目使用此工具来将 Lambda 函数和运行时编译为 AWS Lambda 的本机机器代码。创建的二进制可在自定义运行时使用的标准 Lambda 执行环境中执行。


AWS Lambda 可运行创建的函数以响应多个本机事件,例如通过 Application Load Balancer (ALB) 的 HTTP 请求。ALB 可触发函数来处理请求。



调用函数的事件包含请求元数据和主体。在本文中,我将说明如何构建可处理事件的函数。函数将返回 HTTP 响应作为处理结果。

先决条件

您需要源代码编辑器来为 Lambda 函数创建源文件,以及为包管理器创建包规范。如果您喜欢开源,并且希望快速开始创建函数,那么 Visual Studio Code 和 Dart Code 插件是理想之选。插件需要您获取 Dart 开发工具包来使用其大部分功能。

创建、构建和部署 Dart 函数

要开始,先为您的 Dart 包创建文件夹,然后为其添加包规范。您需要通过规范来使用 pub 包管理器,其可通过规范中的信息来管理 Dart 程序的依赖项和环境。


以下命令可为包创建文件夹:


Bash


bash $ > mkdir my_lambda && cd $_
复制代码


在文件夹中,通过以下内容创建 pubspec.yaml 文件:


Bash


name: my_lambdaenvironment:  sdk: ">=2.6.0 <3.0.0"dependencies:  aws_lambda_dart_runtime:    git: https://github.com/awslabs/aws-lambda-dart-runtime.gitdev_dependencies:  build_runner:
复制代码


这是包规范。如此可将 Dart 运行时指定为程序的依赖项。将从 Dart Lambda 运行时存储库的主分支获取包,直至 AWS 在 pub.dev(一个公开可用的包存储库)上成为发布者。


接下来,创建 main.dart 文件并在您偏好的源代码编辑器中打开。将以下 Dart 程序复制到文件中:


Bash


import 'package:aws_lambda_dart_runtime/aws_lambda_dart_runtime.dart';
void main() async { /// This demo's handling an ALB request. final Handler<AwsALBEvent> helloALB = (context, event) async { final response = '''<html><header><title>My Lambda Function</title></header><body>Success! I created my first Dart Lambda function.</body></html>'''; /// Returns the response to the ALB. return InvocationResult( context.requestId, AwsALBResponse.fromString(response)); }; /// The Runtime is a singleton. /// You can define the handlers as you wish. Runtime() ..registerHandler<AwsALBEvent>("hello.ALB", helloALB) ..invoke();}
复制代码


程序会在运行时中将 helloALB 函数注册为 hello.ALB 句柄。句柄是代码中特定函数的标识符,AWS Lambda 运行函数时可调用此标识符。调用请求包含运行时应执行的句柄,并且运行时会将此句柄映射到届时运行的真实函数。程序中的 hello.ALB 句柄的类型将归为 AwsALBEvent 事件。因此,AWS Lambda 调用 hello.ALB 句柄时,运行时预计会收到 Application Load Balancer 事件。AwsALBEvent 就是 Dart 运行时中一个便捷的封套,可从 Application Load Balancer 事件中将 JSON 提取到 Dart 数据结构。请参阅 AWS Lambda 的 Dart 运行时文档,了解所有可用事件。


下一步是编译函数,其中包括警告。dart2native 工具不提供跨平台编译器支持(请参阅 #28617)。如果您未使用 Linux x86-64 平台,这一点十分重要。未在此平台上编译的二进制无法在 AWS Lambda 上执行。您可学习如何使用 Docker 在其他平台上编译函数。

使用 Docker 编译

首先,如果尚未安装 Docker,则您必须在操作系统中安装 Docker。如果您不了解 Docker,请参阅“什么是 Docker?”。如需编译函数,您需要使用官方的 google/dart Docker 容器。


接下来,继续逐步操作,生成二进制。如果您使用持续集成,则以下步骤均可自动执行。如需查看 build.sh 脚本示例,请查看 Dart Lambda 运行时项目示例文件夹中的脚本。


首先,在容器中挂载包,然后为其创建交互式 Shell:


Bash


bash $ > docker run -v $PWD:/app -w /app -it google/dart /bin/bash
复制代码


该命令会在 /app 输入工作目录。通过 pub get 获取所需依赖项。这样便准备就绪,可以将 Dart 程序编译为机器代码,并且 Dart 运行时为:


Bash


bash $ > dart2native main.dart -o bootstrap
复制代码


运行 ls -lh 应该具有以下输出。bootstrap 文件为编译后的 main.dart 程序;有意将此文件命名为 bootstrap。Lambda 运行时在启动该函数时会执行名为 bootstrap 的任何文件(请参阅“自定义 AWS Lambda 运行时”文档):


Bash


-rwxr-xr-x 1 root root 8.0M Feb 3 10:03 bootstrap-rw-r--r-- 1 root root 665 Feb 3 09:55 main.dart-rw-r--r-- 1 root root 9.2K Feb 3 10:02 pubspec.lock-rw-r--r-- 1 root root 193 Feb 3 09:25 pubspec.yaml
复制代码


最后一步,使用 exit 在容器中退出交互式 Shell。

在 Linux 上编译

如果您是在 Linux x86-64 上运行,则不必使用 Docker 容器;不过,您必须在开发环境中安装 Dart


Bash


bash $ > pub get && dart2native  main.dart -o bootstrap
复制代码


这些命令获取依赖项,并将 main.dart 中的程序编译为引导二进制文件,此二进制文件可在自定义 AWS Lambda 中执行。您将会看到一条确认已成功生成该二进制文件的消息。由于自定义运行时在启动函数时将执行任何名为 bootstrap 的文件,因此该二进制文件命名为 bootstrap

构建函数

bootstrap 二进制文件为最后一步准备就绪时,即可对其进行部署:通过 zip -j lambda.zip bootstrap 创建该二进制文件的 .zip 文件。lambda.zip 文件包用于在 AWS Lambda 中部署函数。

在 AWS Lambda 中部署函数

您所创建的函数的目的是通过 Application Load Balancer HTTP(S) 请求对该函数进行调用(请参阅文章“Lambda 函数作为 Application Load Balancers 的目标”)。该函数预期运行时将返回一个 ALB 调用事件,此调用事件由函数封装在 Dart 对象中。


下一步,导航至 AWS Lambda 控制台,然后单击创建函数



从零开始创建函数并将其命名为 myLambda。下一步,从运行时下拉菜单中提供您自己的 bootstrap。为 Lambda 创建一个新执行角色并将其命名为myLambdaExecutionRole,不过,您也可以使用现有角色。最后,单击创建函数以创建函数。会出现一条告知您已成功创建函数的消息,您也会被重定向至该函数的详细信息页面。


下一步,部署 Lambda 函数。在函数代码部分下,选择上传 .zip 文件。将处理器重命名为 hello.ALB,此名称为您在我们 main.dart 中注册的处理器的名称。然后,在函数包下单击上传,从 my_lambda 文件夹选择 lambda.zip。按保存以上传函数包。



您已成功部署 Lambda 函数。

测试函数

下一步是测试函数是否有效以及处理器是否由运行时调用。因此,您必须创建一个测试事件并调用函数。


要测试事件并调用函数,单击选择测试事件,然后选择配置测试事件选项。



将测试事件命名为 myLambdaALBTestEvent,并将文档中的 JSON 用于事件主体:


Json


{    "requestContext": {        "elb": {            "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-279XGJDqGZ5rsrHC2Fjr/49e9d65c45c6791a"        }    },    "httpMethod": "GET",    "path": "/lambda",    "queryStringParameters": {        "query": "1234ABCD"    },    "headers": {        "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",        "accept-encoding": "gzip",        "accept-language": "en-US,en;q=0.9",        "connection": "keep-alive",        "host": "lambda-alb-123578498.us-east-2.elb.amazonaws.com",        "upgrade-insecure-requests": "1",        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",        "x-amzn-trace-id": "Root=1-5c536348-3d683b8b04734faae651f476",        "x-forwarded-for": "72.12.164.125",        "x-forwarded-port": "80",        "x-forwarded-proto": "http",        "x-imforwards": "20"    },    "body": "",    "isBase64Encoded": false}
复制代码



单击创建来创建测试事件。myLambdaALBTestEvent 应已创建并按预选设置出现在下拉菜单中。



准备就绪,可以测试事件了。单击测试按钮以触发测试事件。展开执行过程的详情,将显示对请求的成功响应,其中包括示例 HTTP 响应主体。



既然您已经成功测试了函数,说明您已经准备好了将函数与实际 ALB 进行关联。您可以参阅“Lambda 函数作为 Application Load Balancer 的目标”一文了解更多信息。

自定义事件

Dart 运行时支持自定义事件。此类事件并非 AWS 平台及其服务的原生事件,而是由客户自己所创建的。要创建自定义事件,您需要创建事件的类别,并使用运行时的实例注册事件。运行时以单例模式执行,以便在您的代码结构灵活使用并可避免创建多个实例。


为新的自定义事件创建 MyCustomEvent 类别。类别仅需实施 MyCustomEvent.fromJson(Map<String, dynamic> json) 工厂方法。在稍后查找事件处理器的 MyCustomEvent 以及通过事件的 JSON 表达方式创建事件时,运行时会调用此方法。


Bash


class MyCustomEvent {  factory MyCustomEvent.fromJson(Map<String, dynamic> json) =>      MyCustomEvent(json);  const MyCustomEvent();}
Register the MyCustomEvent with the runtime as follows:Runtime() ..registerEvent((Map<String, dynamic> json) => MyCustomEvent.from(json);The full example of a MyCustomEvent looks like this:import 'package:aws_lambda_dart_runtime/aws_lambda_dart_runtime.dart';class MyCustomEvent { factory MyCustomEvent.fromJson(Map<String, dynamic> json) => MyCustomEvent(json); const MyCustomEvent();}void main() async { final Handler successHandler = (context, event) async { return InvocationResult(context.requestId, "SUCCESS"); }; Runtime() ..registerEvent((Map<String, dynamic> json) => MyCustomEvent.from(json)) ..registerHandler("doesnt.matter", successHandler) ..invoke();}.
复制代码


处理器函数在 Context 对象中传递。该对象包含关于来自 Lambda 运行时界面的调用的信息,例如 requestIdregionfunctionName。参阅 AWS Lambda 的 Dart 运行时文档,了解有关自定义事件和完整 API 的更多信息。

结论

Dart Lambda 运行时目前仍处于早期阶段。维护人员希望获得您的反馈意见以帮助其发展。维护人员尤其希望了解您实验所用的工作负载,或尚不完善和需要提供支持的工作负载。您可以访问 aws-lambda-dart-runtime Github 存储库,分享您的经验或提交问题。


本文转载自 AWS 技术博客。


原文链接:https://amazonaws-china.com/cn/blogs/china/introducing-a-dart-runtime-for-aws-lambda/


2020-02-27 17:05669

评论

发布
暂无评论
发现更多内容

低代码应用搭建平台,基于低代码快速开发管理系统

互联网工科生

低代码 低代码开发 JNPF

一文了解Java低代码开发平台

互联网工科生

Java 低代码 JNPF java低代码开发平台

Wise 的平台工程 KPI 探索之旅

快乐非自愿限量之名

KPI 平台工程 wise

前端如何入门 Go 语言

高端章鱼哥

前端 Go 语言

深入理解并发编程艺术-内存模型篇

Java并发 内存模型 Java内存模型 多线程高并发 高并发编程

C语言中.与->的用法介绍

梦笔生花

智慧垃圾分类处理3D可视化系统

2D3D前端可视化开发

智慧环卫 智慧垃圾处理 智慧垃圾分类 智慧环保

AWS 亚马逊云科技 1 亿美金入局AIGC,哪些AI云服务已经可以对标微软、谷歌?

B Impact

官宣!2023云原生编程挑战赛正式启动

阿里巴巴云原生

阿里云 云原生 云原生编程挑战赛

集团公司该如何构建信息化系统?

优秀

信息化系统

强化学习从基础到进阶-常见问题和面试必知必答[5]::梯度策略、添加基线(baseline)、优势函数、动作分配合适的分数(credit)

汀丶人工智能

人工智能 深度学习 强化学习 6 月 优质更文活动

OSPFv3:第三版OSPF除了支持IPv6,还有这些强大的特性!

wljslmz

OSPF 6 月 优质更文活动

国外主机引领你的网站征服全球!

一只扑棱蛾子

国外主机

谷歌推出“能讲会听”的大语言模型 AudioPaLM,实现语音理解和生成

Zilliz

谷歌 AIGC 大语言模型

EMQ & 明道云:零代码高效构建工业物联网设备管理平台

EMQ映云科技

IoT 工业物联网 明道云

超越极限!80Gbps高速传输,让您的数据瞬间飞速传递

镭速

强化学习从基础到进阶-案例与实践[5]:梯度策略、添加基线(baseline)、优势函数、动作分配合适的分数(credit)

汀丶人工智能

人工智能 深度学习 强化学习 6 月 优质更文活动

实录分享 | Alluxio Operator一体化部署方案

Alluxio

分布式 operator Alluxio 大数据 开源 容器化部署

利用Flutter和小程序容器打造更强大的用户体验

FinFish

flutter 小程序 跨端开发 小程序容器 跨端框架

基于smardaten无代码快速开发一个智慧城管系统

陈橘又青

无代码开发

SOFAStack 的下一个五年

SOFAStack

开源 SOFA 程序员 java

数字孪生城市革命!低代码开发平台引爆智慧未来

EquatorCoco

低代码 低代码开发 数字孪生城市

AI+低代码:解密AI赋能,释放创新力量!

快乐非自愿限量之名

AI 低代码

Java并行流指北

javalover123

并行 Java' 并行流

表单设计领域天花板,表单引擎最全设计

codebee

镭速——简单、快速、自动备份数据到云端

镭速

3DCAT实时云渲染助力上海市乡村振兴可视化平台,展现数字乡村的魅力

3DCAT实时渲染

云渲染 数字孪生实时云渲染

2023-06-25:redis中什么是缓存穿透?该如何解决?

福大大架构师每日一题

redis 福大大架构师每日一题

App Store——OpenAI 的MaaS模式或将上线,与Microsoft、Salesforce 争To B客户

B Impact

建筑产业变革肇始,华为提笔写下新《营造法式》

脑极体

全屋智能

从幕后走到台前!过去十年,我们在阿里云如何建设可观测体系?

阿里巴巴云原生

阿里云 云原生 可观测

适用于 AWS Lambda 的 Dart 运行时简介_语言 & 开发_AWS_InfoQ精选文章