无服务器 - 打包依赖项
在上一章中,我们了解了如何在无服务器中使用插件。我们专门研究了 Python 需求插件,并了解了如何使用它来将 numpy、scipy、pandas 等依赖项与 lambda 函数的应用程序代码捆绑在一起。我们甚至看到了部署需要 numpy 依赖项的函数的示例。我们看到它在本地运行良好,但在 AWS Lambda 控制台上,如果您使用的是 Windows 或 Mac 计算机,则会遇到错误。我们来了解一下为什么该函数在本地运行但部署后不运行。
如果您查看错误消息,您会得到一些提示。我特别提到一行 - “导入 numpy C 扩展失败。” 现在,许多重要的Python包如numpy、pandas、scipy等都需要编译C扩展。如果我们在 Windows 或 Mac 机器上编译它们,那么 Lambda(Linux 环境)在尝试加载它们时会抛出错误。所以重要的问题是,可以采取什么措施来避免这个错误。进来码头工人!
什么是码头工人?
根据维基百科的说法,docker 是一组平台即服务(PaaS)产品,它使用操作系统级虚拟化来交付称为容器的软件包中的软件。如果你再仔细浏览一下 docker 的维基百科页面,你会发现一些更相关的说法:Docker 可以将应用程序及其依赖项打包在一个可以在任何 Linux、Windows 或 macOS 计算机上运行的虚拟容器中。这使得应用程序能够在各种位置运行,例如本地、公共云和/或私有云。我想经过以上的阐述应该就很清楚了。我们出现错误,因为在 Windows/Mac 上编译的 C 扩展在 Linux 中不起作用。
我们可以通过将应用程序打包到可以在任何操作系统上运行的容器中来简单地绕过该错误。docker 在后台为实现操作系统级虚拟化所做的工作超出了本章的范围。
安装docker
您可以前往https://docs.docker.com/engine/install/来安装 Docker Desktop。如果您使用的是 Windows 10 家庭版,Windows 版本应至少为 1903(2019 年 5 月更新)。因此,您可能需要在安装 Docker Desktop 之前升级 Windows 10 操作系统。Windows 专业版或企业版没有此类限制。
在无服务器中使用 dockerizePip
在您的计算机上安装 Docker Desktop 后,您只需在 serverless.yml 文件中添加以下内容即可使用 docker 打包您的应用程序和依赖项 -
custom: pythonRequirements: dockerizePip: true
请注意,如果您从上一章开始就一直跟着我,那么您可能已经将代码部署到 lambda 一次。这将在您的本地存储中创建一个静态缓存。默认情况下,Serverless 将使用该缓存来捆绑依赖项,因此不会创建 docker 容器。因此,为了强制 Serverless 创建使用 docker,我们将在 pythonRequirements 中添加另一条语句 -
custom: pythonRequirements: dockerizePip: true useStaticCache: false #not necessary if you will be deploying the code to lambda for the first time.
如果您是第一次部署到 lambda,则最后一条语句不是必需的。一般来说,您应该将 useStaticCache 设置为 true,因为当您没有对依赖项或它们必须打包的方式进行任何更改时,这将为您节省一些打包时间。
添加这些内容后,serverless.yml 文件现在看起来像 -
service: hello-world-python provider: name: aws runtime: python3.6 profile: yash-sanghvi region: ap-south-1 functions: hello_world: handler: handler.hello timeout: 6 memorySize: 128 plugins: - serverless-python-requirements custom: pythonRequirements: dockerizePip: true useStaticCache: false #not necessary if you will be deploying the code to lambda for the first time.
现在,当您运行sls deploy -v命令时,请确保 docker 在后台运行。在 Windows 上,您只需在“开始”菜单中搜索 Docker Desktop,然后双击该应用程序即可。您很快就会收到一条消息,表明它正在运行。您还可以通过 Windows 中电池图标附近的小弹出窗口来验证这一点。如果您可以在那里看到 docker 图标,则它正在运行。
现在,当您在 AWS Lambda 控制台上运行函数时,它就可以工作了。恭喜!
但是,在 AWS Lambda 控制台的“函数代码”部分中,您会看到一条消息,显示“您的 Lambda 函数“hello-world-python-dev-hello_world”的部署包太大,无法启用内联代码编辑”。但是,您仍然可以调用您的函数。
似乎添加 Numpy 依赖项使包大小太大,因此我们甚至无法在 lambda 控制台中编辑应用程序代码。我们如何解决这个问题?请继续阅读下一章来找出答案。