
- Serverless 教程
- Serverless - 首页
- Serverless - 简介
- Serverless - 安装
- Serverless - 部署函数
- Serverless - 区域、内存大小、超时时间
- Serverless - 服务
- Serverless - 定时 Lambda 函数
- Serverless - API 网关触发的 Lambda 函数
- Serverless - 包含/排除
- Serverless - 插件
- Serverless - 打包依赖项
- Serverless - 层创建
- Serverless - 使用 DynamoDB 的 REST API
- Serverless - Telegram 回声机器人
- Serverless 有用资源
- Serverless - 快速指南
- Serverless - 有用资源
- Serverless - 讨论
Serverless - 层创建
什么是层?
层是一种隔离代码块的方法。假设您想在应用程序中导入 NumPy 库。您信任该库,并且几乎没有机会更改该库的源代码。因此,如果您不希望 NumPy 的源代码弄乱您的应用程序工作区,您会怎么做呢?简单来说,您只需要 NumPy 放在其他地方,与您的应用程序代码隔离。层允许您完全做到这一点。您可以简单地将所有依赖项(NumPy、Pandas、SciPy 等)捆绑到一个单独的层中,然后在 serverless 中的 lambda 函数中简单地引用该层。就是这样!捆绑在该层中的所有库现在都可以导入到您的应用程序中。同时,您的应用程序工作区保持完全整洁。您只需查看应用程序代码进行编辑。

照片由 Iva Rajovic 拍摄于 Unsplash,表示代码在层中的分离
层真正酷的一点是它们可以在函数之间共享。假设您部署了一个带有包含 NumPy 和 Pandas 的 python-requirements 层的 lambda 函数。现在,如果另一个 lambda 函数需要 NumPy,您无需为此函数部署单独的层。您可以简单地使用前一个函数的层,它也可以与新函数一起正常工作。
这将节省您在部署期间的大量宝贵时间。毕竟,您只需要部署应用程序代码。依赖项已存在于现有层中。因此,许多开发人员将依赖项层保留在单独的堆栈中。然后,他们在所有其他应用程序中使用此层。这样,他们就不需要一遍又一遍地部署依赖项。毕竟,依赖项相当庞大。仅 NumPy 库本身就大约 80 MB。每次更改应用程序代码(可能只有几 KB)时都部署依赖项将非常不方便。
添加依赖项层只是一个例子。还有其他几个用例。例如,serverless.com 上提供的示例涉及使用 FFmpeg 工具创建 GIF。在该示例中,他们将 FFmpeg 工具存储在一个层中。总而言之,AWS Lambda 允许我们为每个函数最多添加 5 个层。唯一的条件是 5 个层和应用程序的总大小应小于 250 MB。
创建 python-requirements 层
现在让我们看看如何使用 serverless 创建和部署包含所有依赖项的层。为此,我们需要 serverless-python-requirements 插件。此插件仅适用于 Serverless 1.34 及更高版本。因此,如果您使用的是 <1.34 版本,则可能需要升级您的 Serverless 版本。您可以使用以下命令安装插件:
sls plugin install -n serverless-python-requirements
接下来,您将此插件添加到 serverless.yml 文件的 plugins 部分,并在 custom 部分提及其配置:
plugins: - serverless-python-requirements custom: pythonRequirements: dockerizePip: true layer: true
在这里,dockerizePip - true 启用 docker 的使用,并允许您在 docker 容器中打包所有依赖项。我们在上一章讨论了使用 docker 打包。layer - true 告诉 serverless python 依赖项应存储在单独的层中。现在,在这一点上,您可能想知道 serverless 如何理解要打包哪些依赖项?答案如插件章节所述,在于 requirements.txt 文件中。
定义层插件和自定义配置后,您可以按如下方式将层添加到 serverless 中的各个函数中:
functions: hello: handler: handler.hello layers: - { Ref: PythonRequirementsLambdaLayer }
关键字 PythonRequirementsLambdaLayer 来自 CloudFormation 参考。通常,它源自层的名称。语法为 'LayerNameLambdaLayer'(标题大小写,无空格)。在我们的例子中,由于层名称是 python 需求,因此引用变为 PythonRequirementsLambdaLayer。如果您不确定 lambda 层的名称,可以通过以下步骤获取:
运行 sls package
打开 .serverless/cloudformation-template-update-stack.json
搜索 'LambdaLayer'
Explore our latest online courses and learn new skills at your own pace. Enroll and become a certified expert to boost your career.
在同一区域中的另一个函数中使用现有层
正如我在开头提到的,层真正酷的一点是能够在您的函数中使用现有层。这可以通过使用现有层的 ARN 轻松完成。使用 ARN 将现有层添加到函数的语法非常简单:
functions: hello: handler: handler.hello layers: - arn:aws:lambda:region:XXXXXX:layer:LayerName:Y
就是这样。现在,具有指定 ARN 的层将与您的函数一起工作。如果层包含 NumPy 库,您可以继续在您的“hello”函数中调用 import numpy。它将运行而不会出现任何错误。
如果您想知道从哪里可以获取 ARN,实际上非常简单。只需导航到 AWS 控制台中包含该层的函数,然后单击“层”。

当然,如果层不属于您的账户,则需要公开共享或专门与您的账户共享。稍后将详细介绍。
此外,请记住,层应与您的应用程序兼容。不要期望与 node.js 运行时兼容的层能够与在 python3.6 运行时中创建的函数一起运行。
非需求/通用层
如开头所述,层的主要功能是隔离代码块。因此,它们不需要仅包含依赖项。它们可以包含您指定的任何代码段。在 custom 中的 pythonRequirements 中调用 layer: true 是 serverless-python-requirements 插件实现的一种快捷方式。但是,要创建通用层,serverless.yml 中的语法(如 serverless 文档 中所述)如下:
layers: hello: path: layer-dir # required, path to layer contents on disk name: ${opt:stage, self:provider.stage, 'dev'}-layerName # optional, Deployed Lambda layer name description: Description of what the lambda layer does # optional, Description to publish to AWS compatibleRuntimes: # optional, a list of runtimes this layer is compatible with - python3.8 licenseInfo: GPLv3 # optional, a string specifying license information # allowedAccounts: # optional, a list of AWS account IDs allowed to access this layer. # - '*' # note: uncommenting this will give all AWS users access to this layer unconditionally. retain: false # optional, false by default. If true, layer versions are not deleted as new ones are created
由于提供了注释,因此各种配置参数不言而喻。除了“path”之外,所有其他属性都是可选的。path 属性是您希望从应用程序代码中隔离的任意目录的路径。它将被压缩并发布为您的层。例如,在 serverless 上的示例项目 中,他们将 FFmpeg 工具托管在一个层中,他们在名为“layer”的单独文件夹中下载该工具,并在 path 属性中指定该文件夹。
layers: ffmpeg: path: layer
如前所述,我们可以在 layers 属性中添加最多 5 个层。
要将这些通用层用于您的函数,您可以再次使用 CloudFormation 参考或指定 ARN。
允许其他账户访问层
只需在 'allowedAccounts' 属性中提及账户编号,即可为更多账户提供对您的层的访问权限。例如:
layers: testLayer: path: testLayer allowedAccounts: - 999999999999 # a specific account ID - 000123456789 # a different specific account ID
如果要使层可公开访问,可以在 allowedAccounts 中添加 '*':
layers: testLayer: path: testLayer allowedAccounts: - '*'