在CloudFront访问时触发RDS lambda



我通过CloudFront从我的S3 Bucket提供静态JS文件,我想监视访问它们的人,我不希望通过CloudWatch这样做,我想自己记录它。

对于每个到CloudFront的请求,我都希望触发一个lambda函数,该函数将有关请求的数据插入到我的MySQL RDS实例中。

但是CloudFront限制了Viewer Request Viewer Response触发器太多,比如1秒超时(太少,无法连接MySQL),没有VPC配置到lambda(因此我甚至无法访问RDS子网)等等。

实现这一目标的最佳方式是什么?设置一个API Gateway,我将如何向那里发送请求?

处理从CloudFront访问的静态内容(或任何内容)的典型方法是启用日志记录,然后处理日志文件。

要启用CloudFront Edge事件(包括处理和更改事件),请查看Lambda@Edge.

Lambda@Edge

我会先启用日志记录,然后监视一段时间的流量。当不良行为者攻击你的网站(CloudFront Distribution)时,他们将产生巨大的流量。这可能会导致使用Lambda Edge产生一些可观的账单。我还建议查看亚马逊WAF,以帮助减轻拒绝服务攻击,这可能有助于Lambda处理量。

这似乎是一个次优策略,因为CloudFront在触发器代码运行时暂停请求/响应处理——Lambda@Edge触发器必须在继续处理请求或响应之前完成执行,因此超时时间很短。

CloudFront提供的日志每小时被多次丢弃(取决于流量负载)到您选择的存储桶中,您可以从S3事件通知中捕获、解析并插入数据库。

然而。。。

如果您真的需要实时捕获,您最好的选择可能是在VPC内创建第二个Lambda函数,该函数接受提供给Lambda@Edge触发

然后,在查看器请求或查看器响应触发器的代码中,您所需要做的就是使用内置的AWS SDK异步调用您的第二个Lambda函数,并将事件传递给它。

这样,日志记录任务就完成了,您不需要等待响应,CloudFront处理就可以继续。

我建议,如果你真的想走这条路,这将是最好的选择。一个Lambda函数可以很容易地调用另一个函数,即使第二个函数不在同一个帐户、区域或VPC中,因为调用是通过与Lambda服务的端点API通信来完成的。

但是,仍然有一些优化的空间,因为你必须从另一个方面Lambda@Edge考虑在内,它与此间接相关:

lambda 没有VPC配置

这有一个重要的原因。你的Lambda@Edge触发代码在最靠近边缘位置的区域中运行,该边缘位置正在处理每个特定查看器的流量。你的Lambda@Edge函数在us-east-1中提供,但它随后被复制到所有区域,如果CloudFront需要它,就可以运行。

因此,当您调用上面提到的第二个Lambda函数时,您实际上会接触到第二个函数区域中的Lambda API——无论哪个区域处理Lambda@Edge触发此特定请求。

这意味着两个区域之间的距离越远,延迟就越大。

这是您真正的最佳解决方案(出于性能目的)稍微复杂一些:不是L@E函数异步调用第二个Lambda函数,而是通过向Lambda API发出请求。。。您可以在每个区域创建一个SNS主题,并为每个主题订阅2nd Lambda函数。(SNS可以跨区域调用Lambda函数。)然后Lambda@Edge触发器代码只需向自己区域的SNS主题发布一条消息,该主题将立即返回响应并异步调用远程Lambda函数(第二个函数,位于特定区域的VPC中)。在您的Lambda@Edge代码中,环境变量process.env.AWS_REGION为您提供了当前运行的区域,因此您可以使用它来确定如何以最小的延迟将消息发送到正确的SNS主题。(测试时,这始终是us-east-1)。

是的,这有点复杂,但它似乎是在不给请求处理带来大量延迟的情况下完成您想要做的事情的方法——Lambda@Edge将信息尽快移交给另一个服务,该服务将负责在数据库中实际生成日志消息。

Lambda和关系数据库在并发性、连接和连接池方面提出了严峻的挑战。有关更多信息,请参阅本Lambda数据库指南。

我建议使用Lambda@Edge作为记录访问的第一步,与为更高并发性而构建的服务进行对话。例如,您可以Lambda@Edge函数将访问记录写入SQS,然后让后台工作人员从SQS读取到RDS。

以下是Lambda@Edge与STS交互以读取一些配置。它可以很容易地进行重构以写入SQS。

最新更新