亚马逊AWS官方博客

AWS Lambda 新增功能 – 使用任何编程语言和共享通用组件

我仍记得 2014 年宣布推出 AWS Lambda 时那激动人心的时刻! 四年过去了,客户将 Lambda 函数用于许多不同的用例。例如,iRobot 使用 AWS Lambda 为其 Roomba 机器人真空吸尘器提供计算服务,Fannie Mae 为数百万抵押贷款运行 Monte Carlo 模拟,Bustle 提供数十亿次数字内容请求

今天,我们将介绍两项新功能,这些功能将使无服务器开发变得更加轻松:

  • Lambda Layers,一种集中管理跨多个函数共享的代码和数据的方法。
  • Lambda Runtime API,一个使用任何编程语言或特定语言版本来开发您的函数的简单接口。

这两项功能可以一起使用:运行时可以作为层共享,以便开发人员可以在编写 Lambda 函数时选择它们并使用自己喜欢的编程语言。

我们来详细了解它们的工作原理。

Lambda Layers

在构建无服务器应用程序时,通常使用通过 Lambda 函数共享的代码。它可以是您的自定义代码,是为了简化业务逻辑的实施,由您添加的多个函数或标准库使用。

以前,您必须将此共享代码与使用它的所有函数一起打包和部署。现在,您可以将常用组件放在 ZIP 文件中并将其作为 Lambda 层上传。您的函数代码不需要更改,并且可以像通常那样引用层中的库。

同时,还可以对层进行版本控制以管理更新,每个版本都是不可变的。删除版本或撤消使用它的权限时,之前使用它的函数将继续有效,但您将无法创建新函数。

在配置函数时,最多可以引用五个层,可以选择其中一个层作为运行时。调用函数时,将按照您提供的顺序在 /opt 中安装层。 顺序很重要,因为层都是在同一路径下提取的,因此每个层都可能覆盖前一个层。此方法可用于自定义环境。例如,第一层可以是运行时,第二层可以添加所需库的特定版本。

函数和层的整体未压缩大小取决于通常的解压缩部署包大小限制

层可以在 AWS 账户中使用,在账户之间共享,也可以与广泛的开发人员社区公开共享。

使用层具有许多优势。例如,您可以使用 Lambda 层实现以下目的:

  • 实现依赖项和自定义业务逻辑之间关注点的分离。
  • 使您的函数代码更小,让您集中更多精力专注于想要构建的内容。
  • 加快部署速度,因为必须打包和上传的代码更少,并且可以重用依赖项。

根据我们的客户反馈,为了提供如何使用 Lambda 层的示例,我们发布了一个公共层,它包括两个热门 Python 科学库 NumPySciPy。这个预构建且经过优化的层可以帮助您快速启动数据处理和机器学习应用程序。

除此之外,您还可以找到来自 Datadog、Epsagon、IOpipe、NodeSource、Thundra、Protego、PureSec、Twistlock、Serverless 和 Stackery 等合作伙伴用于应用程序监控、安全性和管理的层。

使用 Lambda Layers

我现在可以在 Lambda 控制台中管理自己的层:

我现在不想创建新层,而是在函数中使用现有的层。我创建一个新的 Python 函数,在函数配置中,我可以看到没有引用的层。我选择添加一个层:

我从与我的函数运行时兼容的层列表中选择具有 NumPy 和 SciPy 的层,并使用最新版本:

添加层后,单击“保存”以更新函数配置。如果您使用多个层,则可以在此处调整它们与函数代码合并的顺序。

要在我的函数中使用层,我只需要从 NumPy 和 SciPy 导入我需要的功能即可:

import numpy as np
from scipy.spatial import ConvexHull

def lambda_handler(event, context):

    print("\nUsing NumPy\n")

    print("random matrix_a =")
    matrix_a = np.random.randint(10, size=(4, 4))
    print(matrix_a)

    print("random matrix_b =")
    matrix_b = np.random.randint(10, size=(4, 4))
    print(matrix_b)

    print("matrix_a * matrix_b = ")
    print(matrix_a.dot(matrix_b)
    print("\nUsing SciPy\n")

    num_points = 10
    print(num_points, "random points:")
    points = np.random.rand(num_points, 2)
    for i, point in enumerate(points):
        print(i, '->', point)

    hull = ConvexHull(points)
    ("The smallest convex set containing all",
        num_points, "points has", len(hull.simplices),
        "sides,\nconnecting points:")
    for simplex in hull.simplices:
        print(simplex[0], '<->', simplex[1])

我运行函数,查看日志,可以看到一些有趣的结果。

首先,我使用 NumPy 执行矩阵乘法(矩阵和向量通常用于表示神经网络的输入、输出和权重):

random matrix_1 =
[[8 4 3 8]
[1 7 3 0]
[2 5 9 3]
[6 6 8 9]]
random matrix_2 =
[[2 4 7 7]
[7 0 0 6]
[5 0 1 0]
[4 9 8 6]]
matrix_1 * matrix_2 = 
[[ 91 104 123 128]
[ 66 4 10 49]
[ 96 35 47 62]
[130 105 122 132]]

然后,我使用 SciPy 高级空间算法来计算我自己很难构建的内容:找到包含平面上的点列表的最小“凸集”。例如,这可以在 Lambda 函数中使用,该函数接收来自多个地理位置(对应于建筑物、客户位置或设备)的事件,以便以有效的方式将类似事件以可视化的形式“分组”在一起:

10 个随机点:
0 -> [0.07854072 0.91912467]
1 -> [0.11845307 0.20851106]
2 -> [0.3774705 0.62954561]
3 -> [0.09845837 0.74598477]
4 -> [0.32892855 0.4151341 ]
5 -> [0.00170082 0.44584693]
6 -> [0.34196204 0.3541194 ]
7 -> [0.84802508 0.98776034]
8 -> [0.7234202 0.81249389]
9 -> [0.52648981 0.8835746 ]
包含全部 10 个点的最小凸集有 6 个边,
连接点:
1 <-> 5
0 <-> 5
0 <-> 7
6 <-> 1
8 <-> 7
8 <-> 6

在构建此示例时,无需安装或打包依赖项。我可以快速迭代函数的代码。部署非常快,因为我不需要包含大型库或模块。

为了直观呈现 SciPy 的输出,我可以轻松创建一个额外的层来导入绘图库 matplotlib。在上一个函数的末尾添加几行代码,我现在可以将一个图像上传到 Amazon Simple Storage Service (S3),该图像显示“凸集”如何包含所有点:

    plt.plot(points[:,0], points[:,1], 'o')
    for simplex in hull.simplices:
        plt.plot(points[simplex, 0], points[simplex, 1], 'k-')
        
    img_data = io.BytesIO()
    plt.savefig(img_data, format='png')
    img_data.seek(0)

    s3 = boto3.resource('s3')
    bucket = s3.Bucket(S3_BUCKET_NAME)
    bucket.put_object(Body=img_data, ContentType='image/png', Key=S3_KEY)
    
    plt.close()

Lambda Runtime API

您现在可以在创建或更新函数时选择自定义运行时:

做出此选择后,函数必须包含(在其代码或层中)一个名为 bootstrap 的可执行文件,负责代码(可以使用任何编程语言)和 Lambda 环境之间的通信。

运行时引导程序使用简单的基于 HTTP 的接口来获取新调用的事件负载,并从函数返回响应。接口终端节点和函数处理程序的信息作为环境变量共享。

为了执行代码,您可以使用可在 Lambda 执行环境中运行的任何内容。例如,您可以为您选择的编程语言提供解释器。

如果要管理或发布自己的运行时,只需要了解 Runtime API 的工作原理即可。作为开发人员,您可以快速使用与您共享的运行时作为层。

我们很快就会推出这些开源运行时:

  • C++
  • Rust

我们还会与合作伙伴合作提供更多开源运行时:

  • Erlang (Alert Logic)
  • Elixir (Alert Logic)
  • Cobol (Blu Age)
  • N|Solid (NodeSource)
  • PHP (Stackery)

Runtime API 是我们在 Lambda 中支持新语言的未来。例如,这就是我们为 Ruby 语言提供支持的方式。

现已推出

您可以通过控制台或 AWS 命令行界面 (CLI) 在提供 Lambda 的所有区域使用运行时和层。您还可以使用 AWS 无服务器应用程序模型 (SAM) 和 SAM CLI 来通过这些新功能测试、部署和管理无服务器应用程序。

使用运行时和层无需额外费用。 层的存储计入 AWS Lambda 的区域函数存储限制

要了解有关使用 Runtime API 和 Lambda 层的更多信息,请不要错过 12 月 11 日由首席开发人员倡导者 Chris Munns 主办的网络研讨会。

我对这些新功能倍感兴奋,请告诉我您接下来要构建的内容!