1

语境

我目前正在实施一项功能,通过使用 PHP 和 Firebase 的网络表单来安排特定时期的通知。

要发送通知,我使用 Firebase 并将通知发送到 Android/Ios。

为了安排通知,我使用了ATlinux 服务,因为它似乎比 更适合cron,因为cron它以特定频率运行而AT不是,它在特定时间运行。

关于 AT 的手册页:手册页 AT

示例代码

/usr/bin/php `send_notification.php` | at 2021-07-11 15:40

这将在 linux 上创建一个文件,该文件将在 2021-07-11 15:40 期间仅运行一次。

问题

AT服务,如,在CRON操作系统上的目录中创建代表作业的文件。

1 - 如果 AWS 上的机器进行扩展,作业可能会重复,因此会多次发送通知。(注:我对机器缩放了解不多,但我相信它应该会发生)

2 - 如果机器由于包含某些功能或类似的东西而处于停机状态,我相信它目前的工作方式不会被执行。

3 - 另一个问题,但不是主要问题,如果我使用的是 docker 容器。由于 Ubuntu + PHP 在容器内,如果我重新启动容器,作业文件可能会丢失,所以在这种情况下,我相信一个解决方案是使用卷,但现在这不是我的问题,因为目前的应用程序仅使用 AWS EB 上的一台机器和 PHP 映像。

怀疑

  • 有什么解决方案可以使用 PHP 来解决这个重复的工作问题吗?

  • 使用的方法AT是最合适的吗?我看到很多人都在谈论使用CRON,但 CRON 会多次运行这项工作,对我来说,这不是我想要的。

4

1 回答 1

1

我认为您需要一个地方,将保留计划和完成的通知,独立于您使用的内容,cron 或 at。

如果我有这样的任务,我会坚持这样的解决方案:运行特殊脚本,“scheduler.php”每 1 分钟(或更多,例如 5 分钟)由 cron 执行,这将检查一些日志文件(或远程数据库以防万一几台机器)并查看是否有任何新行。如果存在新行并且它包含过去的时间戳和“已调度”状态,则脚本将锁定它并运行您的“sender.php”。之后,它将将该行标记为“完成”。存储中的每一行都应包含要运行的时间戳以及“已调度”、“正在运行”和“已完成”三种状态之一。

使用这种方法,您可以通过将所需时间和状态“计划”添加到存储中来计划新通知。请注意,计划时间和实际通知之间可能会有一点延迟,具体取决于 cron 间隔,但我认为这并不重要。

这将允许您在不同的机器上运行任意数量的 cron,并保证每项工作都将完成一次。

重要提示:如果您将采用此方案,请确保您的 scheduler.php 在单个原子操作中读取和更新存储,以防止多个 cron 之间的竞争条件。文件锁定或“选择更新”就可以了。

于 2021-07-11T20:42:48.730 回答