在核心上运行 Lambda 函数 AWS IoT Greengrass - AWS IoT Greengrass

AWS IoT Greengrass Version 12023 年 6 月 30 日进入延长寿命阶段。有关更多信息,请参阅AWS IoT Greengrass V1维护政策。在此日期之后,AWS IoT Greengrass V1不会发布提供功能、增强功能、错误修复或安全补丁的更新。在上面运行的设备AWS IoT Greengrass V1不会中断,将继续运行并连接到云端。我们强烈建议您迁移到 AWS IoT Greengrass Version 2,这样可以添加重要的新功能支持其他平台

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

在核心上运行 Lambda 函数 AWS IoT Greengrass

AWS IoT Greengrass为您在其中创作的用户定义代码提供了容器化的 Lambda 运行时环境。AWS Lambda部署到AWS IoT Greengrass核心的 Lambda 函数在内核的本地 Lambda 运行时中运行。本地 Lambda 函数可由本地事件、来自云端的消息和其他来源触发,从而为客户端设备带来本地计算功能。例如,您可以使用 Greengrass Lambda 函数筛选设备数据,然后再将数据传输到云端。

要将 Lambda 函数部署到内核,您可以将该函数添加到 Greengrass 组(通过引用现有 Lambda 函数),为该函数配置特定于组的设置,然后部署该组。如果该函数访问AWS服务,则还必须向 Gre engrass 组角色添加所有必需的权限。

您可以配置决定 Lambda 函数运行方式的参数,包括权限、隔离、内存限制等。有关更多信息,请参阅使用组特定的配置控制 Greengrass Lambda 函数的执行

注意

利用这些设置,还可以在 Docker 容器中运行 AWS IoT Greengrass。有关更多信息,请参阅在 Docker 容器中运行 AWS IoT Greengrass

下表列出了受支持的 AWS Lambda 运行时以及它们可以在其上运行的 AWS IoT Greengrass 核心软件版本。

语言或平台 GGC 版本
Python 3.8 1.11
Python 3.7 1.9 或更高版本
Python 2.7 * 1.0 或更高版本
Java 8 1.1 或更高版本
Node.js 12.x * 1.10 或更高版本
Node.js 8.10 * 1.9 或更高版本
Node.js 6.10 * 1.1 或更高版本
C、C++ 1.6 或更高版本

* 您可以在支持的版本上运行使用这些运行时的 Lambda 函数AWS IoT Greengrass,但不能在中创建它们。AWS Lambda如果您设备上的运行时间与为该函数指定的 AWS Lambda 运行时不同,则可以通过在中选择自己的运行时。FunctionRuntimeOverride FunctionDefintionVersion有关更多信息,请参阅CreateFunctionDefinition。有关支持的运行时的更多信息,请参阅《AWS Lambda开发人员指南》中的运行时支持政策

Greengrass Lambda 函数的软件开发工具包

AWS提供了三个软件开发工具包,可在内核上运行的 Greengrass Lambda 函数使用它们。AWS IoT Greengrass这些开发工具包在不同的软件包中,因此,函数可以同时使用它们。要在 Greengrass Lambda 函数中使用软件开发工具包,请将其包含在您上传到的 Lambda 函数部署包中。AWS Lambda

AWS IoT Greengrass 核心开发工具包

使本地 Lambda 函数能够与核心进行交互,以便:

  • 与 AWS IoT Core 交换 MQTT 消息。

  • 与 Greengrass 组中的连接器、客户端设备和其他 Lambda 函数交换 MQTT 消息。

  • 与本地影子服务交互。

  • 调用其他本地 Lambda 函数。

  • 访问秘密资源

  • 流管理器交互。

AWS IoT Greengrass在上提供以下语言和平台的 AWS IoT Greengrass Core SDK GitHub。

要在 Lambda 函数部署包中包含AWS IoT Greengrass核心 SDK 依赖项,请执行以下操作:

  1. 下载与您的 Lambda 函数运行时相匹配的 AWS IoT Greengrass Core SDK 包的语言或平台。

  2. 解压缩下载的程序包以获取软件开发工具包。软件开发工具包是 greengrasssdk 文件夹。

  3. 包含greengrasssdk在包含您的函数代码的 Lambda 函数部署包中。这是您在创建 Lambda 函数AWS Lambda时上传到的包。

 

StreamManagerClient

只有以下 AWS IoT Greengrass 核心开发工具包可用于流管理器操作:

  • Java SDK(1.4.0 或更高版本)

  • Python SDK(1.5.0 或更高版本)

  • Node.js SDK(v1.6.0 或更高版本)

要使用适用于 Python 的AWS IoT Greengrass核心 SDK 与直播管理器进行交互,必须安装 Python 3.7 或更高版本。您还必须安装依赖项才能包含在您的 Python Lambda 函数部署包中:

  1. 导航到包含该 requirements.txt 文件的开发工具包目录。此文件列出了依赖项。

  2. 安装开发工具包依赖项。例如,运行以下 pip 命令将它们安装在当前目录中:

    pip install --target . -r requirements.txt

 

在AWS IoT Greengrass核心设备上安装适用于 Python 的核心开发工具包

如果你正在运行 Python Lambda 函数,也可以使用pip在核心设备上安装适用于 Python 的AWS IoT Greengrass核心开发工具包。然后,您无需在 Lambda 函数部署包中包含软件开发工具包即可部署函数。有关更多信息,请参阅 greengrasssdk

此支持适用于具有大小限制的核心。我们建议您尽可能将软件开发工具包包含在 Lambda 函数部署包中。

 

AWS IoT GreengrassMachine Learning

使本地 Lambda 函数能够使用作为机器学习资源部署到 Greengrass 核心的机器学习 (ML) 模型。Lambda 函数可以使用软件开发工具包调用作为连接器部署到核心的本地推理服务并与之交互。Lambda 函数和机器学习连接器也可以使用软件开发工具包将数据发送到机器学习反馈连接器进行上传和发布。有关更多信息,包括使用此开发工具包的代码示例,请参阅ML 图像分类连接器连接器 ML 对象检测ML 反馈连接器

下表列出了对于各开发工具包版本支持的语言或平台以及它们可以在其中运行的 AWS IoT Greengrass 核心软件的版本。

SDK 版本 语言或平台 必需的 GGC 版本 更改日志
1.1.0 Python 3.7 或 2.7 1.9.3 或更高版本 添加了 Python 3.7 支持和新的 feedback 客户端。
1.0.0 Python 2.7 1.7 或更高版本 首次发布。

有关下载信息,请参阅AWS IoT Greengrass ML 开发工具包软件

AWS 开发工具包

允许本地 Lambda 函数直接调用AWS服务,例如 Amazon S3、DynamoDB 和。AWS IoT AWS IoT Greengrass要在 Greengrass Lambda 函数中使用AWS软件开发工具包,必须将其包含在部署包中。当您在与AWS IoT Greengrass核心软件AWS开发工具包相同的软件包中使用软件开发工具包时,请确保您的 Lambda 函数使用正确的命名空间。当核心处于离线状态时,Greengrass Lambda 函数无法与云服务通信。

入门资源中心下载AWS软件开发工具包。

有关创建部署包的更多信息,请参阅创建并打包 Lambda 函数入门教程或AWS Lambda开发人员指南中的创建部署包

迁移基于云的 Lambda 函数

AWS IoT Greengrass核心软件开发工具包遵循AWS软件开发工具包编程模型,可以轻松地将为云开发的 Lambda 函数移植到在核心上运行的 Lambda 函数。AWS IoT Greengrass

例如,以下 Python Lambda 函数使用some/topic在云端向主题发布消息:AWS SDK for Python (Boto3)

import boto3 iot_client = boto3.client("iot-data") response = iot_client.publish( topic="some/topic", qos=0, payload="Some payload".encode() )

要将函数移植到AWS IoT Greengrass内核,请在import语句和client初始化中,将boto3模块名称更改为greengrasssdk,如以下示例所示:

import greengrasssdk iot_client = greengrasssdk.client("iot-data") iot_client.publish(topic="some/topic", qos=0, payload="Some payload".encode())
注意

AWS IoT Greengrass 核心开发工具包仅支持发送 QoS 为 0 的 MQTT 消息。有关更多信息,请参阅消息服务质量

编程模型之间的相似性还使您能够在云中开发 Lambda 函数,然后以最少的努力将其AWS IoT Greengrass迁移到云中。Lambda 可执行文件不在云端运行,因此在部署之前,您无法使用 AWS SDK 在云中开发它们。

按别名或版本引用 Lambda 函数

Greengrass 群组可以按别名(推荐)或按版本引用 Lambda 函数。使用别名可以更轻松地管理代码更新,因为在更新函数代码时,您不必更改订阅表或组定义。相反,您只需将别名指向新的函数版本即可。在群组部署期间,别名会解析为版本号。在使用别名时,解析的版本将在部署时更新为别名指向的版本。

AWS IoT Greengrass不支持 $LATEST 版本的 Lambda 别名。$LATEST 版本不绑定到不可变的、已发布的函数版本,并且可以随时更改,这与版本不可变AWS IoT Greengrass的原则背道而驰。

通过代码更改来更新 Greengrass Lambda 函数的常见做法是使用在 Greengrass 群组和订阅中命名的PRODUCTION别名。在将 Lambda 函数的新版本升级到生产环境时,请将别名指向最新的稳定版本,然后重新部署该组。您也可以使用这种方法回滚到以前的版本。

Greengrass Lambda 函数的通信流

Greengrass Lambda 函数支持多种与群组其他成员、本地服务和云服务(包括服务)进行通信的方法。AWS IoT Greengrass AWS

使用 MQTT 消息进行通信

Lambda 函数可以使用由订阅控制的发布-订阅模式发送和接收 MQTT 消息。

此通信流允许 Lambda 函数与以下实体交换消息:

  • 组中的客户机设备。

  • 组中的连接器。

  • 该组中的其他 Lambda 函数。

  • AWS IoT.

  • 本地设备影子服务。

订阅会定义消息源、消息目标以及用于将消息从源路由到目标的主题。发布到 Lambda 函数的消息将传递给该函数的注册处理程序。订阅实现了更高的安全性并提供可预测的交互。有关更多信息,请参阅MQTT 消息传递工作流中的托管订阅

注意

当核心处于离线状态时,Greengrass Lambda 函数可以与客户端设备、连接器、其他函数和本地影子交换消息,但发送到的消息会排队。AWS IoT有关更多信息,请参阅云目标的 MQTT 消息队列

其他通信流

  • 为了与核心设备上的本地设备和卷资源以及机器学习模型进行交互,Greengrass Lambda 函数使用特定于平台的操作系统接口。例如,你可以在 Python 函数的操作系统模块中使用该open方法。要允许函数访问某个资源,函数必须与该资源关联,或者为其授予了 read-onlyread-write 权限。有关更多信息,包括AWS IoT Greengrass核心版本的可用性,请参阅使用 Lambda 函数和连接器访问本地资源从 Lambda 函数代码访问机器学习资源

    注意

    如果您在没有容器化的情况下运行 Lambda 函数,则无法使用连接的本地设备和卷资源,必须直接访问这些资源。

  • Lambda 函数可以使用AWS IoT Greengrass核心软件开发工具包中的Lambda客户端来调用 Greengrass 组中的其他 Lambda 函数。

  • Lambda 函数可以使用AWS软件开发工具包与AWS服务进行通信。有关更多信息,请参阅 AWSSDK

  • Lambda 函数可以使用第三方接口与外部云服务通信,类似于基于云的 Lambda 函数。

注意

当核心处于离线状态时,Greengrass Lambda 函数无法AWS与云服务或其他云服务通信。

检索输入 MQTT 主题(或主旨)

AWS IoT Greengrass使用订阅来控制客户端设备、Lambda 函数和群组中的连接器之间以及AWS IoT与本地影子服务之间的 MQTT 消息交换。订阅定义消息源、消息目标以及用于路由消息的 MQTT 主题。如果目标是 Lambda 函数,则在源发布消息时调用该函数的处理程序。有关更多信息,请参阅使用 MQTT 消息进行通信

以下示例显示 Lambda 函数如何从传递给处理程序context的中获取输入主题。具体方法是通过从上下文层次结构 (context.client_context.custom['subject']) 访问 subject 密钥。该示例还会解析输入 JSON 消息,然后发布解析的主题和消息。

注意

在 AWS IoT Greengrass API 中,订阅的主题由 subject 属性表示。

import greengrasssdk import logging client = greengrasssdk.client('iot-data') OUTPUT_TOPIC = 'test/topic_results' def get_input_topic(context): try: topic = context.client_context.custom['subject'] except Exception as e: logging.error('Topic could not be parsed. ' + repr(e)) return topic def get_input_message(event): try: message = event['test-key'] except Exception as e: logging.error('Message could not be parsed. ' + repr(e)) return message def function_handler(event, context): try: input_topic = get_input_topic(context) input_message = get_input_message(event) response = 'Invoked on topic "%s" with message "%s"' % (input_topic, input_message) logging.info(response) except Exception as e: logging.error(e) client.publish(topic=OUTPUT_TOPIC, payload=response) return

要测试函数,请使用默认配置设置将其添加到组中。然后,添加以下订阅并部署该组。有关说明,请参阅 模块 3 (第 1 部分):上的 Lambda 函数AWS IoT Greengrass

目标 主题筛选条件
IoT 云 此函数 test/input_message
此函数 IoT 云 test/topic_results

部署完成后,调用该函数。

  1. 在AWS IoT控制台中,打开 MQTT 测试客户端页面。

  2. 通过选择 “订阅test/topic_results主题” 选项卡来订阅主题

  3. 选择 “发布到test/input_message主题” 选项卡,向主题发布消息。对于此示例,您必须在 JSON 消息中包含 test-key 属性。

    { "test-key": "Some string value" }

    如果成功,此函数会将输入主题和消息字符串发布到 test/topic_results 主题。

Greengrass Lambda 函数的生命周期配置

Greengrass Lambda 函数生命周期决定了函数何时启动以及它如何创建和使用容器。生命周期还确定如何保留位于函数处理程序外部的变量和预处理逻辑。

AWS IoT Greengrass 支持按需(默认)或长时间生存的生命周期:

  • 按需函数在调用时启动,并在没有要执行的任务时停止。除非具有可重复使用的现有容器,否则,函数调用将创建单独的容器(或沙盒)以处理调用。发送到函数的数据可以由任何容器提取。

    按需 函数的多次调用可以并行运行。

    在创建新的容器时,不会保留在函数处理程序外部定义的变量和预处理逻辑。

  • 当AWS IoT Greengrass核心启动并在单个容器中运行时,长寿命(或固定)函数会自动启动。发送到函数的所有数据由相同的容器提取。

    多个调用将排入队列,直到执行了以前的调用。

    将为处理程序的每次调用保留在函数处理程序外部定义的变量和预处理逻辑。

    当您需要在没有任何初始输入的情况下开始工作时,使用寿命长的 Lambda 函数非常有用。例如,在长时间存在的函数开始接收设备数据时,该函数可以加载并开始处理 ML 模型以使其准备就绪。

    注意

    请记住,长时间生存的函数具有与其处理程序调用关联的超时。如果要执行无限期运行的代码,您必须在处理程序外部启动该代码。确保在处理程序外部没有阻止代码而导致函数可能无法完成初始化。

    除非内核停止(例如,在群组部署或设备重启期间)或函数进入错误状态(例如处理程序超时、未捕获的异常或超过其内存限制),否则这些函数将运行。

有关容器重用的更多信息,请参阅 AWS Compute 博客AWS Lambda中的了解容器重用

Lambda 可执行文件

此功能适用于AWS IoT Greengrass酷睿 v1.6 及更高版本。

Lambda 可执行文件是一种 Greengrass Lambda 函数,可用于在核心环境中运行二进制代码。它允许您在本地执行特定于设备的功能,并从较小的编译代码占用空间中受益。Lambda 可执行文件可以通过事件调用、调用其他函数和访问本地资源。

Lambda 可执行文件仅支持二进制编码类型(不支持 JSON),但除此之外,您可以在 Greengrass 组中管理它们,并像其他 Greengrass Lambda 函数一样部署它们。但是,创建 Lambda 可执行文件的过程与创建 Python、Java 和 Node.js Lambda 函数的过程不同:

  • 您不能使用AWS Lambda控制台创建(或管理)Lambda 可执行文件。您只能使用 API 创建 Lambda 可执行文件。AWS Lambda

  • 您可以将函数代码AWS Lambda作为已编译的可执行文件上传到,其中包含适用于 C 的 C AWS IoT Greengrass ore SDK

  • 您将可执行文件名称指定为函数处理程序。

Lambda 可执行文件必须在其函数代码中实现某些调用和编程模式。例如,main 方法必须:

  • 调用 gg_global_init 以初始化 Greengrass 内部全局变量。必须先调用该函数,然后再创建任何线程以及调用任何其他 AWS IoT Greengrass 核心开发工具包函数。

  • gg_runtime_start用在 Greengrass Lambda 运行时中注册函数处理程序。必须在初始化时调用该函数。调用该函数将导致运行时环境使用当前线程。可选的 GG_RT_OPT_ASYNC 参数指示该函数不要阻止,而是为运行时环境创建新的线程。该函数使用 SIGTERM 处理程序。

以下片段是 simple_handler.c 代码示例中的main方法。 GitHub

int main() { gg_error err = GGE_SUCCESS; err = gg_global_init(0); if(err) { gg_log(GG_LOG_ERROR, "gg_global_init failed %d", err); goto cleanup; } gg_runtime_start(handler, 0); cleanup: return -1; }

有关要求、限制和其他实现细节的更多信息,请参阅适用于 C 的 C AWS IoT Greengrass ore SDK

创建 Lambda 可执行文件

在编译代码和软件开发工具包后,使用 AWS Lambda API 创建 Lambda 函数并上传编译后的可执行文件。

注意

必须使用与 C89 兼容的编译器编译您的函数。

以下示例使用创建函数 CLI 命令创建 Lambda 可执行文件。该命令指定:

  • 处理程序的可执行文件名称。它必须是编译的可执行文件的确切名称。

  • 包含编译的可执行文件的 .zip 文件的路径。

  • 运行时环境的 arn:aws:greengrass:::runtime/function/executable。这是所有 Lambda 可执行文件的运行时间。

注意

对于role,您可以指定任何 Lambda 执行角色的 ARN。 AWS IoT Greengrass不使用此角色,但需要参数才能创建该函数。有关 Lambda 执行角色的更多信息,请参阅AWS Lambda开发人员指南中的AWS Lambda权限模型

aws lambda create-function \ --region aws-region \ --function-name function-name \ --handler executable-name \ --role role-arn \ --zip-file fileb://file-name.zip \ --runtime arn:aws:greengrass:::runtime/function/executable

接下来,使用 AWS Lambda API 发布一个版本并创建别名。

  • 使用 publish-version 发布一个函数版本。

    aws lambda publish-version \ --function-name function-name \ --region aws-region
  • 使用 create-alias 创建指向刚发布的版本的别名。我们建议您在将 Lambda 函数添加到 Greengrass 组时按别名引用它们。

    aws lambda create-alias \ --function-name function-name \ --name alias-name \ --function-version version-number \ --region aws-region
注意

AWS Lambda控制台不显示 Lambda 可执行文件。要更新函数代码,您还必须使用 AWS Lambda API。

然后,将 Lambda 可执行文件添加到 Greengrass 组,将其配置为在其特定于组的设置中接受二进制输入数据,然后部署该组。您可以在 AWS IoT Greengrass 控制台中或者使用 AWS IoT Greengrass API 执行此操作。