运行 在 aws 上部署的 spring 服务的单个实例上的 chron 作业

Running chron job on a single instance of spring service deployed on aws

我需要每周 运行 仅在 java spring 服务的单个实例上 运行 对集群中的多个 aws 实例执行 chron 作业.我可以自由地在不同的集群中生成相同服务的实例来处理 chron 作业的特殊负载。我正在考虑在服务中实现一个 sqs 侦听器模块,一旦新集群上特别配置的 lambda 发布 sqs 消息,该模块就会被触发。由于此 lambda 只会在新实例的队列中发布,因此应该可以确保使用专用集群资源一次最多只有一个 chron 工作(用于处理一次数据)。如果我们想在所有实例中保持应用程序级代码和配置相同,这种方法是否适合实现指定的 chron 作业 运行 计划?

我对 was 有点“生疏”(上次在几年前使用过),但总的来说,你所描述的似乎是一个很好的解决方案,但有以下注意事项:

  1. 您应该确保 amazon SQS 提供“exactly once”语义,否则在某些情况下您可能最终会触发消息两次。我知道这样做,但也许你应该以某种方式打开它并且价格会略有变化,你应该检查

  2. 确保您以正确的方式处理作业执行过程中可能出现的异常,以便在异常导致 sqs 驱动程序运行时作业不会在另一个实例上重新执行以消息将返回到 sqs 队列的方式与 sqs 服务器交互

  3. 如果实例在作业执行期间停止会发生什么情况 - 当然可能发生,期望的行为是什么? Re运行 另一个实例上的作业?又或者放手,靠的是下一次作业运行也会“掩盖”上一期,这取决于实际的应用逻辑

  4. 您的应用程序将依赖于“外部调度程序”(当然是通过 lambda 实现的),因此您的应用程序本身不会有任何 cron 触发逻辑。这只是需要注意的事情,而不是您可以做的事情。这可能是好事,也可能不是好事,具体取决于您的环境。例如,如果您想测试 CI 中的作业调度或您应该部署 Lambda 并且能够实际发送消息以触发作业执行的东西。另外,您应该有可用的 SQS。

所以,我再次看到您可以使它正常工作,当然,根据您的应用程序架构,其他解决方案也可能适用,因为您可以使用 Kubernetes Jobs、Redis 和任何形式的分布式缓存来协调作业实际上在哪个节点上 运行s,很多事情。

使用Redis也可以实现。因为,它在单线程中工作,所以即使多个节点请求同时读取 redis,也只有一个线程能够这样做,稍后可以更新,这样其他线程就没有资格使用 运行 cron 逻辑。如果我们使用像 INCR 这样的命令在一次调用中更新和 return 值,就可以实现这一点。例如。 set :-(K, {0,timestamp}) (由所有节点完成) incr K returned 1 to only 1 node rest will get 2,3...