java - 当 aws autoscaling 组成员被销毁并且有未完成的 Spring 异步线程在执行操作时会发生什么?

标签 java spring asynchronous tomcat8 amazon-ec2

我有一个 Spring 应用程序,现在使用 @Async 方法来处理一些非必要但信息丰富的内容。效果很好。

我想将一些新的处理移至应用程序的这个角落,但我不完全理解如果通过 AWS 关闭它所运行的 ec2 实例,会发生什么情况。

此应用程序作为自动缩放组的一部分在 AWS 中的 Tomcat 8 上运行。我们经常部署,并且扩展和缩减很多,因此机器终止是例行公事。我知道这可能会导致某些线程在中途停止,这是可以接受的。

现有用例:“通过 Slack 向中层管理人员报告最后一小时的销售情况。”

我知道机器关闭可能会导致 Slack 消息无法发布,这是正常的。这只是中层管理人员。

新用例:“每天凌晨 5:00 通过电子邮件向高级管理层报告最后一天的销售情况。”

如果此报告需要很长时间才能运行,则如果电源线被拉断,运行该报告的线程很可能会停止。

我知道如何防范这种情况,并通过 Redis 等使事情变得“有点原子”,但这不会扩展到连续失败或当任务持续时间最终超过 ec2 生命周期时,我想更深入地了解如何ec2 实例“shutdown”命令会影响当前正在通过 @Async 方法调用运行代码的运行中 jvm 线程。

我不想在 Lambda 或其他任何带外运行这些东西,因为我们的域位于此代码库中并且经常更新。

我用谷歌搜索了一下这个主题,几乎所有结果都会产生其应用程序容器在这种情况下不会关闭的主题,这与我正在寻找的信息相反。 p>

谢谢!

-尼尔

最佳答案

这里有几点需要注意:

  1. 直接回答您的问题:

    What happens when an aws autoscaling group member is destroyed and there are outstanding Spring async threads doing stuff?

    线程获得 InterruptedException。

  2. 您描述的场景并不真正适合自动缩放实例。这些是为处理交通而设计的。您的场景更多的是关于作业处理。专用(可能是预定的)实例(队列)更适合于此。如果您需要运行其中许多实例,您可以安排 Spot 实例以降低成本。如果您通常在流量处理机器上运行作业,听起来您在应用程序中混合了关注点,最好将它们分开。

  3. 在实例中,我将运行对作业进行一些状态管理的应用程序。您可以使用像 DynamoDB 这样的持久存储来自己编写它(Elasticache 也可以,但是如果失败了怎么办?),或者让其他一些工具为您完成它(例如 Oozie、Chronos/Airflow,具体取决于您的首选语言)。

    如果自己实现,每个报告间隔(假设一天)都会有一条记录。状态机将为:未运行(与不存在相同)、正在运行失败完成。除Not Running 之外的所有作业都将具有上次更新时间戳,该时间戳将针对正在运行的作业定期持续更新。还有谁拥有正在运行的作业的实例/进程/线程标识符。如果作业被标记为“正在运行”,但更新丢失的时间间隔超过 X 个时间间隔,您可以将前一个运行程序声明为失败,并且观察到此情况的下一个实例可以获取此作业的所有权(更新所有者)。

关于java - 当 aws autoscaling 组成员被销毁并且有未完成的 Spring 异步线程在执行操作时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36640132/

相关文章:

Java:用于在后台线程中读取文本文件的 Activity 指示器

java - Java 中的多线程帮助

c# - 当我的应用程序启动时,如何在我的 Xamarin Forms 中调用此异步方法?

Java、Hashmap、数据类型转换

Java数据库正确方法

java - 基于环境的 Spring 数据源

java - 无法连接到 websocket 服务器(spring)

java - 我成功登录,但只能在第二次尝试后访问该网站

java - 如何等待异步 Observable 在另一个 Observable 上完成

python - 同时处理 2 个 websocket 连接的最佳方法