【问题标题】:SQS Timeout from Lambda within VPCVPC 内 Lambda 的 SQS 超时
【发布时间】:2020-12-16 19:59:31
【问题描述】:

我有一个 Lambda,它需要在 VPC 上才能与 RDS 和 AWSDocumentDB 等受保护资源进行通信。对于对 3rd 方 API 的某些调用,它还需要能够看到外部世界。为此,我使用 VPC 向导创建了一个同时具有公有子网和私有子网的 VPC。该向导还创建并附加了一个 Internet 网关。

之后,我将我的 Lambda、RDS 实例和 DocumentDb 集群附加到 VPC。但是,从那时起,我就无法使用 NodeJS aws-sdk 从我的 lambda 中与我的 SQS 队列交谈。

我想补充一点,我已经阅读并实施了以下几点:AWS Lambda: Unable to access SQS Queue from a Lambda function with VPC access 但是我仍然无法连接。

这是我所拥有的:

  1. VPC:

    • VPC 具有公共子网和私有子网,以及一个 IG 网关。我使用向导来创建它。我不太了解这里的基础知识。
    • VPC Config(抱歉,这是一个链接,我还不能嵌入。)
    • CIDR's- 向导创建了除最后一个块之外的所有块。我不确定我是否做对了,或者它是否重要,因为向导让我创建了至少一个,我这样做是为了避免 IP 重叠。
    • 由于这是一个开发/原型项目,附加到 VPC 的安全组是“完全开放的”。允许所有入站和出站。
    • 让我知道要显示的其他 VPC 配置,因为我不确定什么有用
  2. 服务端点:

    • 我尝试按照上面链接的文章为 SQS 创建一个服务端点,这就是我所拥有的:endpoint config
    • 我将在 Lambda 部分详细讨论我是如何使用它的。
    • 端点已附加到 VPC
  3. 拉姆达:

  4. 代码

    • 这是我的代码中 SQS 调用的样子:

      • const {SQS} = require('aws-sdk');
        
        // Constructor Init
        const sqs = new SQS({
           apiVersion: '2012-11-05', 
           endpoint: 'https://sqs.us-west-2.amazonaws.com', // not sure if this is 'invoking' the vpc endpoint or not
           region: 'us-west-2'
        });
        
        // Send message
        await sqs.sendMessage({
           MessageBody: 'Test body',
           QueueUrl: 'https://sqs.us-west-2.amazonaws.com/<rest of URI>',
           MessageAttributes: {...someAttrs}
        }).promise();
        
        
        
        

感谢任何帮助,请让我知道我可以提供哪些其他信息。

谢谢!

** 编辑 **

我还应该提到,为了规避整个问题,我开始使用 SQS 作为 Lambda 目标。虽然这确实将消息注入目标队列,但它可能不会随着我的用例扩展。如果需要,我可以进一步详细说明,因为它与实际问题并不完全相关。

** 编辑 8/31/20 **

感谢所有回复,这是一个很大的帮助,让我有了一个解决方案。我会说,任何发现这篇文章的人都是先看:

https://www.youtube.com/watch?v=JcRKdEP94jM

这是我希望在开始这一切之前找到的东西,因为虽然它专门针对 lambdas 互联网访问,但它经历了将 IG 和 Nats 映射到子网的过程,这确实是我错误配置的地方我的vpc。通过这个视频,我重新创建了我的整个 VPC,连接起来更加简洁和容易。 10/10 推荐。

再次感谢!

【问题讨论】:

  • 我遇到了几乎同样的问题,除了我使用的是 python。正如this answer 中所解释的(有解决方法),我的结果是boto3 中的一个错误。

标签: node.js amazon-web-services aws-lambda amazon-sqs amazon-vpc


【解决方案1】:

AWS Lambda 函数应附加到 VPC 中的私有子网

Amazon SQS 存在于 Internet 上,因此 Lambda 函数需要一种访问 SQS 端点的方法。

选项 1:VPC 端点

VPC Endpoint for Amazon SQS 可以在 VPC 和 SQS 终端节点之间提供直接链接,而无需访问 Internet。创建后,VPC 将自动跨 VPC 端点发送 SQS 请求。这是一个不错的简单选项。

选项 2:NAT 网关

如果您在需要 Internet 访问的私有子网中有其他资源,您可以考虑在公共子网中放置 NAT 网关。私有子网需要一个路由表条目,将 Internet 绑定流量 (0.0.0.0/0) 引导到 NAT 网关。

需额外收费。

选项 3:Lambda 目标

如果您的 Lambda 函数通过 Lambda 目标成功地与 SQS 通信,那么 这听起来是个不错的选择!没试过,不过好像是Lambda服务负责把输出直接发给SQS,不用遍历VPC或者Internet。如果这有效,那么我强烈建议继续使用它。我不认为使用这种方法有任何缩放问题。但是,请注意,它仅适用于对 Lambda 的异步调用,并且在同步调用函数或按下 Test 按钮时不起作用。

【讨论】:

  • 感谢您的回复!因此,根据上面的屏幕截图,我将 VPC 必须的所有子网附加到 lambda(一些公共的,一些私有的)。如果我只附加私有子网,我仍然能够与外部(即:Stripe API)资源通信吗?
  • 现在尝试 NAT 解决方案。我创建了一个,但它从未关联到子网。
  • AWS Lambda 函数只能配置为使用私有子网。坦率地说,我建议使用选项 #3 或选项 #1 而不是使用 NAT 网关,因为这会涉及额外的成本(以及更多的复杂性)。
  • 好建议,我认为你是对的。按比例,我之前指的是 AWS 会将您的 lambda 返回的任何内容放在消息正文中。所以在我的用例中,我想处理所有账户的每笔交易。所以第一个查询/lambda 获取所有账户,最初将每个账户作为自己的消息放入队列,因为下游每个账户可能有 10K+ txns。但是现在我必须重新考虑我最初是如何查询帐户的,所以我没有将 1K+ 帐户打包到一条消息中。
  • 也许我可以使用步进函数来创建一些偏移延续,这样我就可以减少每个下游 lambda 的处理量。
【解决方案2】:

我对此的预感是,您的网络配置中某处缺少一条规则 - 数据包被丢弃到您的 SQS 或返回途中(两者都需要逐跳考虑)。

想到的三件事:

  1. 路由:确保子网和路由表具有适当的路由,以便将数据包从 SQS 端点所在的那一个返回到您的私有子网。
  2. 安全组 - 仔细查看涉及的每个 SG。例如,SQS 可能位于限制对其访问的 SG 中。
  3. 网络 ACL - 这些是无状态的,因此您需要确保双方都是开放的,并且请记住,大多数情况下,将涉及返回给请求者的随机端口号。

祝你好运!

【讨论】:

  • 就是这样!我决定仔细检查我的 SG I/O,我注意到一些奇怪的事情:在其专用页面上查看 SG 时,规则看起来很正常。进出都是0.0.0.0/0。然而,当我前往 SQS 端点并从那里查看 SG 时,虽然它是同一个 SG,但它显示了一个入站规则 sg-&lt;id&gt;,这意味着入站流量仅限于 SG 内的任何内容。从那里我单击编辑并删除了该约束,现在它可以工作了!谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-08-07
  • 2019-12-17
  • 1970-01-01
  • 2020-11-14
  • 2017-04-06
  • 2020-12-15
  • 2019-06-06
  • 1970-01-01
相关资源
最近更新 更多