我已经使用 zappa 在 AWS 中部署了 api(Django 应用程序)。我面临冷启动问题。启动应用程序需要近 7-8 秒(代码接近 25 MB)。如何克服这个问题?
在 zappa settings.json 中,我保留了keep_warm=true,但没有用。 我已经编写了lambda函数来使用调度cloudwatch事件来触发api,它正在触发(我可以在zappa日志中看到),但问题没有解决。
我的处理程序的示例代码是:
import json
def lambda_handler(event, context):
# TODO implement
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
我的 zappa 配置是:
{
"dev": {
"aws_region": "ap-south-1",
"django_settings": "api.settings",
"profile_name": "default",
"project_name": "api-public",
"runtime": "python3.6",
"s3_bucket": "api-public",
"slim_handler": true,
"vpc_config" : {
"SubnetIds": [ "subnet-052347e86b94b75d3" ], // use the private subnet
"SecurityGroupIds": [ "sg-0ba3a644d413a2b00","sg-0db0b6de5b14cda33"]
},
"xray_tracing": true,// Optional, enable AWS X-Ray tracing on your lambda function.
"memory_size": 1024, // Lambda function memory in MB. Default 512.
"log_level": "DEBUG", // Set the Zappa log level. Can be one of CRITICAL, ERROR, WARNING, INFO and DEBUG. Default: DEBUG
"keep_warm": true, // Create CloudWatch events to keep the server warm. Default true. To remove, set to false and then `unschedule`.
"timeout_seconds": 300,
"keep_warm_expression": "rate(3 minutes)", // How often to execute the keep-warm, in cron and rate format. Default 4 minutes.
"exclude": [
".git/*",
".gitignore",
"boto3*",
"*botocore*",
"django-debug-toolbar*",
"sqlparse*",
"zappa_settings.json",
"README.md"
],
"lambda_description": "zappa deployment public", // However you want to describe your project for the AWS console. Default "Zappa Deployment".
"extra_permissions": [{ // Attach any extra permissions to this policy. Default None
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": ["arn:aws:lambda:ap-east-1:940180048916:function:api-public-dev"],// AWS Service ARN
}],
}
}
如果您需要对 Django 应用程序进行预热,那么您首先以错误的方式使用 AWS Lambda 函数。(相信我,个人经历)
创建 AWS Lambda 函数是为了向全世界部署轻量级函数。你的Django应用程序是一个沉重的(iest)函数。
AWS Lambda专为生命周期为秒级几分之一的应用程序而设计。 25 MB 本身对 Lambda 函数来说是一个巨大的负载。
请考虑改用轻量级框架作为 Flask。不要克服 Lambda 函数。他们不是为了那个。
请改用 AWS ECS。
你能包括你的 Zappa 配置吗?下面是如何在设置文件的上下文中使用keep_warm
的示例,其中包含更多设置:
{
"production": {
"aws_region": "us-east-1",
"django_settings": "config.zappa",
"profile_name": "zappa",
"project_name": "mydomain",
"runtime": "python3.6",
"s3_bucket": "zappa-mydomain",
"certificate_arn": "arn:aws:acm:us-east-1:272727272727:certificate/eeeeeeee-dddd-cccc-bbbb-aaaaaaaaaaaa",
"domain": "mydomain.com",
"exclude": [
".git/*",
".gitignore",
"boto3*",
"*botocore*",
"django-debug-toolbar*",
"sqlparse*",
"zappa_settings.json",
"README.md"
],
"keep_warm": true,
"timeout_seconds": 300
}
}
祝你好运!
从技术上讲,如果我们可以接受这是 AWS lambda 函数限制之一的事实,这不是问题。
这里的主要问题是,由于这种限制(延迟),我们强迫自己使用 lambda,这显然不符合要求。
如果我们在这种情况下使用 lambda,问题是这样的,
- 保持 lambda 函数存活一段时间会很昂贵! 超级昂贵,显然 lambda(容器)的设计不是为了像那个家伙那样工作!
与其通过 lambda 通常的工作方式并花费您很多钱,我想建议使用 EC2 作为您的 Web 服务器 (API),并在其之上进行自动扩展和负载平衡。
在这种方法中,从 API 返回的响应 - 会更快,因为你的API是唤醒的,正在等待任何请求 - 比您在 Lambda 上使用它便宜,因为 Lambda 执行的计算时间每 GB 秒收取 0.00001667 USD,想象一下您的 lambda 唤醒 10 分钟:)
希望这有帮助! :)
干杯! 猴子
定期命中是简单的技术,但它对同时请求的情况没有帮助。一个 lamdba 实例一次只能处理一个请求。我不确定如何使用 zappa 来做到这一点。然而,有希望的解决方案是使用 docker 检查点
https://www.imperial.ac.uk/media/imperial-college/faculty-of-engineering/computing/public/1819-ug-projects/StenbomO-Refunction-Eliminating-Serverless-Cold-Starts-Through-Container-Reuse.pdf
当然,你可以使记忆翻倍。它不会加倍计费,因为请求的处理速度会更快。
我也有点幻想添加到 zappa 花哨的策略中,例如默认运行 cheep 1M 实例,但检测冷启动并重定向到 3M 实例或 bean,但检查点对于像 django 这样的超大框架似乎更有希望。