通过 Zappa 在 AWS Lambda 中部署的 Django 应用程序的请求时间太长

Zuf*_*fra 6 django amazon-web-services zappa aws-lambda

我最近使用Zappa将 Django 后端应用程序部署到 AWS Lambda 。

在一段时间内未调用 lambda 函数后,发出的第一个请求需要 10 到 15秒的时间才能处理。起初我以为这是因为冷启动,但这次即使是冷启动也是不可接受的。然后,通读 Zappa 的文档,我发现它默认启用keep_warm每 4 分钟向 lambda 函数发送一个虚拟请求以保持温暖的功能;因此,对 lambda 的第一个请求的响应的过度延迟并不是由于冷启动造成的。

然后,我开始使用 AWS X-Ray 和 Cloudwatch Insights 等工具来尝试找到延迟的解释。这是我发现的:

需要很长时间才能处理的调用如下: 在此输入图像描述

用红色划掉的是应用程序使用的环境变量的名称。它们都是直接在 AWS 控制台中定义并分配值的。我不明白的是,首先,为什么需要这么长时间,其次,为什么它说环境变量被转换为None. 该应用程序运行完美(除了第一个请求中的大量延迟之外),因此环境变量在某处正确设置。

此请求每隔两个小时虔诚地发出一次,并且在一段时间内有人第一次调用 lambda 函数,如下图所示:

在此输入图像描述

x 轴上的点对应于 Zappa 保持服务器温暖的虚拟请求。升高的点对应于上图中所示的调用。最后,峰值对应于用户调用。处理时间是处理长调用(第一张图中所示)所需时间和处理客户端向服务器发出的最长 http 请求所需时间的总和。该请求如下:

在此输入图像描述

这是一个常规的登录请求,应该更快地得到解决。其他可能比这个要求更高的请求在不到 100 毫秒的时间内得到了解决。

所以,总结一下:

  1. 有一个 lambda 调用需要 10 秒以上才能解析。这对应于显示的第一张图像。每 2 小时执行一次,当用户在服务器空闲一段时间后向服务器发出请求时执行一次。
  2. 有些请求需要 2 秒以上才能解决,我不知道为什么会这样。
  3. 除了这些先前的函数调用之外,所有其他请求都会在合理的时间范围内得到解决。

非常感谢任何关于为什么这些调用可能花费这么多时间的想法,因为我花了相当长的时间试图自己弄清楚,但我已经没有想法了。先感谢您!

编辑1(28/07/21):为了进一步支持我的怀疑,即这种延迟不是由于冷启动造成的,这里是Cloudwatch/应用程序监控/跟踪中函数的“分段时间线”:

在此输入图像描述

如果是冷启动,延迟应该出现在“初始化”段中,而不是“调用”段中。

编辑 2 (30/07/21):我忘了提及,我之前使用 Elastic Beanstalk 部署了应用程序,并且没有遇到此问题,因此我的代码的性能可能不是这里的问题。

编辑 3 (30/07/21):我在 2016 年的 AWS 论坛中找到了关于这个确切问题的帖子。一位 AWS 工程师提到,对于 VPC 之外的 Lambda 函数(比如我的)来说,这种行为绝不是预期的。然而,没有提供任何答案来解释 10-15 秒延迟的原因。

编辑 4 (03/08/21):我尝试将函数分配的内存加倍(从 512 MB 到 1024 MB),但没有帮助。

sti*_*tel 0

我还对问题添加了一些评论,以解释这可能不是由于冷启动造成的。正如您正确指出的那样,冷启动已明确指示,并且在您的情况下似乎只需要大约 500 毫秒。

这么长时间的冷启动通常仅在 lambda 在 VPC 中运行时才会显现出来。此后,AWS 改变了 lambda 获取网络接口的方式,从而极大地加快了这一过程。

话虽这么说,快速的 Google 搜索让我在其他网站上找到了一些关于 Django 应用程序和延迟加载的有趣讨论。我将在这里分享一些链接(尽管它们与 Lambda 无关),希望它们可以帮助您找到解决方案:

https://community.webfaction.com/questions/11560/django-app-seems-very-slow-to-start-up-10-seconds https://ses4j.github.io/2015/11/23/optimizing -慢-django-rest-framework-性能/

关于 keep_warm 的最后一点。发送这些请求是书中的一个相当老的技巧。但是,请注意,AWS 无法保证 lambda 的保温时间。但是,如果Init duration日志中显示,则可以确定这是冷启动。如果您需要确保 lambda 函数能够快速响应传入请求,则必须使用预配置并发,当然它有自己的价格标签。