如何防止Elastic Beanstalk上长时间运行的作业被终止而不阻塞扩展?

len*_*wal 5 amazon-web-services autoscaling amazon-elastic-beanstalk

我有许多并行工作者在弹性beanstalk工作环境中处理长时间运行的作业.基于队列的长度来缩放基础EC2实例.我的问题是工作人员在处理期间被终止,同时发生了缩放操作.

我最初的防止这种情况的方法如下所示:在收到来自sqs守护程序的消息后,每个worker都在保护他正在运行的EC2实例.当工作人员准备好处理作业时,他再次取消保护EC2实例.这似乎是针对这种情况的推荐方法:https://aws.amazon.com/about-aws/whats-new/2015/12/protect-instances-from-termination-by-auto-scaling/ 和除了事实之外,它没有考虑到任何放置策略.这导致所有实例都受到保护,并且大部分时间都取消了扩展操作.sqs守护进程似乎没有考虑尽可能多的工人填充实例.

我的下一个考虑是在触发缩放操作时停止sqs守护程序,例如使用自动缩放生命周期钩子.但是使用这种方法,终止受保护的实例可能仍然是一个问题(我不知道是否在受保护的实例上触发了钩子).此外,似乎不建议停止sqs守护程序:在Elastic Beanstalk上启动/停止sqsd守护程序以查看SQS队列消息

如何通过弹性beanstalk工作层满足这两个要求(1.不要阻止长时间运行的工作人员和2.尽可能多地运行每个EC2实例的工作人员)?

小智 0

我对 Beanstalk 工作层实例不是很熟悉,但据我所知,它们一次获得 1 个任务,对吗?如果是这样,为什么需要停止 SQS 守护进程,大概是如果正在发生缩减,这是因为工作队列中没有更多任务,因此该实例不应该获得新任务。如果此时恰好有一个节点进来,它不会从 SQS 队列中删除,并且一旦可见性超时结束就会被另一个工作节点拾取。

在实例保护被禁用之前,生命周期挂钩不会被触发,因为它仅在实例被选择终止时启动。

如果您能够在代码中添加一段逻辑,声明“如果任务结束并且没有新任务进入 -> 则禁用此实例上的实例保护”,这样只有没有任务的实例才能被终止。

或者,您可以持续保护所有内容,并通过 Cron 作业定期在实例上运行 bash 脚本,检查当前是否正在运行作业,如果没有则禁用实例保护