从 lambda 函数(django)调用 www.googleapis.com:443 时如何修复超时错误 504

Posted

技术标签:

【中文标题】从 lambda 函数(django)调用 www.googleapis.com:443 时如何修复超时错误 504【英文标题】:How to fix Time Out error 504 when calling www.googleapis.com:443 from lambda function (django) 【发布时间】:2019-11-30 14:00:57 【问题描述】:

我正在设置一个后端 (django) 和前端 (react) 应用程序。在这里,我试图通过 google-auth pypi 包实现 google 登录。所以前端调用 google 登录 -> 获取令牌并将其传递给后端端点,该端点接收令牌并将其传递给 id_token.verify_oauth2_token() 以获取详细信息(名称、用户名电子邮件等)。

问题是它在我的本地主机上运行良好。一旦我使用 Zappa 将 django 包部署到 lambda,HTTPS 连接 (1): www.googleapis.com:443 就会超时。

    升级了 google-auth 包 将域添加到 google api 凭据 传递 google 客户端 ID 来拨打电话

怀疑 AWS 端可能存在不允许它发出外部获取请求的东西。不知道在哪里可以找到这个。

类 GoogleSignIn(APIView):

permission_classes = (permissions.AllowAny,)

def post(self, request, format=None):
    # upon signing in using google sign in, the front end calls /users/google-sign-in, which calls this method. It passes a OneTime googleUserId
    # this methods verifies the one time googleUserId with google to make sure that the signed in user is for our platform.
    # On successful verification, the google side will reply with a 200 response as well as additional information about the user.
    try:
        google_one_time_id = request.data['googleUserId']
        idinfo = id_token.verify_oauth2_token(
            google_one_time_id, requests.Request(), CLIENT_ID)
        if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']:
            raise ValueError('Wrong issuer.') 

预期结果是 200 响应

【问题讨论】:

您是否将 Lambda 函数部署到 VPC 中? 【参考方案1】:

AWS Lambda 函数被授权与外部端点建立连接。如果您的函数部署到 VPC,则必须为 VPC 配置 Internet 访问(连接 Internet 网关的公共子网或具有 NAT 网关的私有子网,您可以在此处阅读更多详细信息https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario2.html

AWS Lambda 默认在 3 秒后超时,如果您的调用需要更多时间,您可以在 lambda 控制台或使用 CLI (https://docs.aws.amazon.com/lambda/latest/dg/resource-model.html) 更改此值

您的问题需要澄清 504 (TimeOut) 是由 Lambda 函数调用还是 id_token.verify_oauth2_token() 调用返回的,在这种情况下,Lambda 超时不是这里的问题。

【讨论】:

我可以确认 VPC 配置了已具有 Internet 网关访问权限的子网。安全组具有到目的地 0.0.0.0/0 的出站规则。感谢您的回复。我不确定这到底是在哪里被阻止的。如何查看它的 lambda 函数还是 id.token? 我会在你的 python 代码中添加一个 try catch + print 语句来检查错误是由 python 运行时还是 lambda 运行时产生的【参考方案2】:

我遇到了这个问题,并且能够通过执行以下步骤来解决它:

    在您的 Lambda 函数有权访问的 VPC 下创建一个子网。 创建一个 NAT 网关并将其添加到您的子网。 通过添加目标:0.0.0.0/0 和目标:nat-xxxxxx 来编辑子网中的路由表关联。

您可以在此处阅读有关如何设置 NAT 网关的更多信息:https://aws.amazon.com/premiumsupport/knowledge-center/nat-gateway-vpc-private-subnet/

【讨论】:

【参考方案3】:

我今天也遇到了超时 lambdas 的问题,我花了很长时间才意识到在我的情况下是内存不足导致了问题。

我已经超时了 1 分钟,但我的 lambda 表达式只是超时了。在CloudWatchLambdas 中的Monitor 选项卡下,您可以看到您为函数分配了多少RAM,以及它实际使用了多少。 当您看到您使用了与分配的相同数量时,您应该为您的函数分配更多内存。

就我而言,我将 RAM 从 128MB 增加到 384MB,现在一切正常 :)

【讨论】:

以上是关于从 lambda 函数(django)调用 www.googleapis.com:443 时如何修复超时错误 504的主要内容,如果未能解决你的问题,请参考以下文章

使用参数从 SNS 调用 Lambda 函数?

从单个Lambda调用多个Lambda

从通用 lambda 调用 `this` 成员函数 - clang vs gcc

如何从 lambda 函数调用秘密管理器

如何从 JAVA 调用 AWS lambda 函数?

如何从我的 EC2 实例调用 AWS Lambda 函数?