当 S3 中的文件更改时,在 Elastic beanstalk 应用程序的所有实例中触发操作

Posted

技术标签:

【中文标题】当 S3 中的文件更改时,在 Elastic beanstalk 应用程序的所有实例中触发操作【英文标题】:Trigger an action in all instances of Elastic beanstalk application when a file in S3 changes 【发布时间】:2017-08-18 02:24:43 【问题描述】:

我在 AWS Elasic Beanstalk 中运行的 spring-boot 应用程序从 Amazon S3 中的某个位置加载数据。数据每 10 分钟刷新一次,我希望 beanstalk 的所有实例都从 S3 重新加载数据。

我有一个巧妙的方法来完成这项工作。我做了以下。

1. Implemented an end point in beanstalk application which, when called, triggers the reload.
2. I have a script that determines the IP address of each beanstalk instance given the beanstalk application's `environment name`.
3. I then iterate through all these IP addresses and call the end point mentioned in point 1 above.

到目前为止,这很有效,因为实例的 IP 地址是可公开寻址的。这将不再是这种情况,因为我们只能使用私有 IP。

触发数据重新加载的正确方法是什么?我在想以下几点:

1. Set up Amazon S3 bucket to generate an event and post to a SNS topic.
2. Have an SNS client in my beanstalk application which subscribes to that topic and listens for events.
3. Upon receiving an event from that topic, trigger the data reload.

我做了(1),但不知道怎么做(2)和(3)。如何订阅 Java 代码中的主题? SNS 仅允许 3 种通知方法 - 使用 SQS(AWS 简单排队服务)、SMS 和通过 HTTP/HTTPS URL。

URL 方法不起作用,因为它只会将请求转发到负载均衡器后面的一个实例。因此,并非所有实例都会重新加载。

SQS 也不会工作,因为一旦一个实例读取了消息,该消息就会出队,而其他实例将不会收到触发消息。

电子邮件也不起作用(或者我不知道如何使它起作用)。

任何帮助/想法?非常感谢指向 Java 代码的指针。

【问题讨论】:

如果有一些数据需要在每个 EBS 实例上重新加载,那么为什么不将数据保留在 S3 本身上呢? 对不起。我没明白你的意思@KaranShah。数据已经驻留在 S3 中。它每 10 分钟更新一次。然后需要提醒 beanstalk 实例来提取刷新的数据。 根据您的描述,您的要求是从 s3 大约每隔 10 分钟将数据加载到您的 EB 实例,对吗?如果您能告知我们为什么计划加载数据的要求,那么为您提供答案会更容易。 @Ashan:beantalk 应用程序需要数据。由于应用程序可能运行多个服务器,每个服务器都需要相同的数据,因此将数据存储在所有实例加载数据的位置是有意义的。所以我将这些数据存储在 S3 中。这些数据是关于产品可用性的,它不断变化。所以每 10 分钟,我在 S3 中更新这些数据(使用后台脚本)。 【参考方案1】:

我和你在同一条船上,我有一个 ElasticBeanstalk 自动扩展应用程序,我希望每个 EC2 实例订阅一个 SNS 主题。因此,我想知道如何构建一个 URL 以用作我的订阅侦听器端点。我不太确定 Java 是否会通过它的 IP 函数获取我的私有地址或公共地址。

我在在线论坛中看到 cmets 批评说,通过在代码中添加 HTTP Post 侦听器来接收消息是一种糟糕的实现(从安全角度来看),仅此一点就意味着它是可能的。然而,在其他情况下谈论 VPC 时,听起来事情又开始崩溃了。

即使我确实解决了上述所有问题,我会遇到的额外问题是在我的开发机器上运行相同的代码,很可能它会使用我无法从 Internet 访问的私有 IP 地址,从而导致我的代码失败如果选择私有 IP 地址,实际上可能在 EC2 实例上出现同样的问题。

根据我目前阅读的内容,您最好使用 Amazon SQS,注册某种发布/订阅队列,然后在超时的情况下轮询来自您的 EC2 实例的更新。

在我的情况下,我需要确定我的应用程序是否正在关闭(ContextListener 将在此处提供帮助)然后停止 SQS 队列接收器循环,因此在我超时后我可能会检查是否设置了关闭标志,如果不再循环。

这似乎比 SNS pub/sub 复杂得多。我想分享我学到的东西,希望它可以同时帮助你/其他人。此外,我还针对 AWS Elastic Beanstalk EC2 实例上下文中的 pub/sub 的堆栈溢出问题启动了 question here。

【讨论】:

以上是关于当 S3 中的文件更改时,在 Elastic beanstalk 应用程序的所有实例中触发操作的主要内容,如果未能解决你的问题,请参考以下文章

使用 AWS Elastic Beanstalk 进行部署时,是不是应该将静态文件存储在单独的 S3 中?

在 Elastic Beanstalk 配置设置中拒绝访问 S3 对象

将目录作为压缩文件从 Elastic MapReduce 上传到 S3

未为 AWS Elastic beanstalk 创建 s3 存储桶

仅当 S3 文件已更改时,如何下载它?

Elastic beanstalk 实例无法访问私有 S3 文件