Serverless 简明教程
Serverless - Packaging Dependencies
在上一个章节中,我们了解了如何将插件与 serverless 结合使用。我们具体介绍了 Python Requirements 插件,了解了如何使用它将 numpy、scipy、pandas 等依赖项与 lambda 函数的应用程序代码捆绑在一起。我们甚至还举例说明了解决 numpy 依赖项所需的函数。我们注意到函数在本地运行得很好,但如果您使用的是 Windows 或 Mac 计算机,则在 AWS Lambda 控制台中运行会遇到错误。让我们来了解一下为什么函数可以在本地运行,但在部署后却无法运行。
In the previous chapter, we saw how to use plugins with serverless. We specifically looked at the Python Requirements plugin and saw how it can be used to bundle dependencies like numpy, scipy, pandas, etc.with your lambda function’s application code. We even saw an example of deploying a function requiring the numpy dependency. We saw that it ran well locally but on the AWS Lambda console, you’d have encountered an error if you are on a Windows or Mac machine. Let’s understand why the function runs locally but doesn’t run after deployment.
如果查看错误信息,您会得到一些提示。我具体指的是一行代码:“导入 numpy C 扩展失败。”如今,numpy、pandas 和 scipy 等诸多重要的 Python 程序包都要求编译 C 扩展。如果在 Windows 或 Mac 计算机上编译这些程序包,那么 Lambda(Linux 环境)在尝试加载它们时会抛出错误。因此,重要的在于,我们可以做些什么来避免此错误。使用 Docker 来解决!
If you look at the error message, you get some hints. I’m specifically referring to one line − 'Importing the numpy C-extensions failed.' Now, many important python packages like numpy, pandas, scipy, etc.require the compilation of C-extensions. If we compile them on a Windows or a Mac machine, then Lambda (linux environment) will throw up an error when trying to load them. So the important question is, what can be done to avoid this error. Come in docker!
What is docker?
根据 Wikipedia 的说法,docker 是一组平台即服务 (PaaS) 产品,它使用操作系统级虚拟化来利用称为容器的程序包交付软件。如果您仔细阅读 Docker 的 Wiki 页面,您会发现其他一些相关说明 – Docker 可以将应用程序及其依赖项打包到虚拟容器中,该容器可以在任何 Linux、Windows 或 macOS 计算机上运行。这使应用程序能够在各种位置中运行,例如:本地、公共云或/和私有云。我认为上述说法应该阐述得非常清楚。我们遇到错误是因为在 Windows/Mac 上编译的 C 扩展无法在 Linux 中运行。
According to Wikipedia, docker is a set of platform as a service (PaaS) products that use OS-level virtualization to deliver software in packages called containers. If you scan the Wikipedia page of docker a bit more, you will come across some more relevant statements − Docker can package an application and its dependencies in a virtual container that can run on any Linux, Windows, or macOS computer. This enables the application to run in a variety of locations, such as on-premises, in a public cloud, and/or in a private cloud. I think it should be very clear after the above statements. We have an error coming up because C-extensions compiled on Windows/Mac don’t work in Linux.
我们可以通过将应用程序打包到可以在任何操作系统中运行的容器中来简单绕过该错误。Docker 在后台执行的操作以实现此操作系统级虚拟化超出了本章节的范围。
We can simply bypass that error by packaging the application in a container that can run on any OS. What docker does in the background to achieve this OS-level virtualization is beyond the scope of this chapter.
Installing docker
您可以前往 https://docs.docker.com/engine/install/ 安装 Docker Desktop。如果您使用的是 Windows 10 家庭版,则 Windows 版本应为 at least 1903 (May 2019 update) 。因此,在安装 Docker Desktop 之前,您可能需要升级 Windows 10 操作系统。Windows 专业版或企业版没有此类限制。
You can head over to https://docs.docker.com/engine/install/ for the installation of Docker Desktop. If you are using Windows 10 Home Edition,the Windows version should be at least 1903 (May 2019 update). Therefore, you may want to upgrade your Windows 10 OS before installing Docker Desktop. No such limitations apply to Windows Pro or Enterprise versions.
Using dockerizePip in serverless
在您的机器上安装了 Docker Desktop 之后,只需对 serverless.yml 文件进行以下补充,即可使用 Docker 来打包应用程序和依赖项 −
Once Docker Desktop has been installed on your machine, you need to make only the following addition to your serverless.yml file to package your applications and dependencies using docker −
custom:
pythonRequirements:
dockerizePip: true
请注意,如果您自上一章节起一直关注我的讲解,那么您很可能已经将代码部署到了 Lambda 中。这会在您的本地存储中创建静态缓存。默认情况下,serverless 将使用该缓存来捆绑依赖项,因此不会创建 Docker 容器。因此,为了强制 serverless 创建使用 Docker,我们将向 pythonRequirements 中添加另一个语句 -
Please note, that if you have been following along with me since the previous chapter, it is likely that you have already deployed code to lambda once.This would have created a static cache in your local storage. By default, serverless would use that cache to bundle dependencies, and therefore, docker container won’t be created.Therefore, to force serverless to create use docker, we will add another statement to 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,因为这将节省一些打包时间,这是在您没有对依赖项或依赖项的打包方式进行任何更改的情况下。
This last statement is not necessary if you are deploying to lambda for the first time. In general, you should set useStaticCache to true, since that will save you some packaging time when you haven’t made any changes to the dependencies or the way they have to be packaged.
添加后,serverless.yml 文件现在看起来像:
With these additions, the serverless.yml file now looks like −
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 图标,则说明它正在运行。
Now, when you run the sls deploy -v command, make sure that docker is running in the background. On Windows, you can just search for Docker Desktop in the Start menu and double click on the app. You will soon get a message that it is running. You can also verify this through the small popup near the battery icon in Windows. If you can see the docker icon there, it is running.

现在,当您在 AWS Lambda 控制台中运行您的函数时,它可以正常工作了。恭喜!!
Now when you run your function on the AWS Lambda console, it would work. Congratulations!!
但是,在 AWS Lambda 控制台中“函数代码”部分中,您会看到一条消息,提示“Lambda 函数“hello-world-python-dev-hello_world”的部署包太大,无法启用内联代码编辑。但是,您仍然可以调用您的函数”。
However, in your 'Function Code' section on the AWS Lambda console, you would be seeing a message saying 'The deployment package of your Lambda function "hello-world-python-dev-hello_world" is too large to enable inline code editing. However, you can still invoke your function.'

看来添加 Numpy 依赖项导致包大小过大,因此,我们甚至无法在 Lambda 控制台中编辑应用程序代码。我们该怎么解决此问题?进入下一章节查找答案。
Seems like the addition of the Numpy dependency has made the bundle size too large and as a result, we cannot even edit our application code in the lambda console. How do we solve that problem? Head on to the next chapter to find out.