我有一个应用程序,我希望用户能够随时添加事件,即只应在用户输入确定的未来特定时间运行的代码块。与 cronjobs 类似,除了在任何时候都可能需要处理数千个此类事件,每个事件都在其特定的到期时间进行。据我了解,crontab 将无法处理它们,因为它并不意味着拥有大量的 cronjobs,此外,我需要精确到秒,而不是分钟。我知道可以以编程方式将 cronjobs 添加到 crontab,但同样,这对于我想要完成的工作来说还不够。
另外,我需要这些是实时的,通过在访问页面时简单地检查是否有到期项目来伪造它们不是解决方案;即使在适当的时间没有访问任何页面,它们也应该触发。我一直在做一些研究以寻找一个理智的解决方案,我读了一些关于队列系统的信息,例如 gearman 和 rabbitmq,但是 FIFO 系统也对我不起作用(添加事件的顺序无关紧要,因为它是完美的可能会添加一个事件以在 1 小时内触发,然后紧接着另一个应该在 10 秒内触发的事件)
到目前为止,我发现的最佳解决方案是构建一个守护进程,即一个脚本,它将持续运行以检查是否有新事件要触发。我知道 PHP 是魔鬼,会泄漏内存等等,但我仍然希望 PHP 守护程序可以稳定运行数周并偶尔重启,只要我生成新的独立进程来执行“繁重”,即事件触发时的实际处理。
所以无论如何,显而易见的问题:
1)这听起来合理吗?有没有更好的方法我可能会失踪?
2)假设我确实实现了守护进程的想法,代码自然需要检索哪些事件是到期的,下面是它的伪代码:
while 1 {
read event list and get only events that are due
if there are due events
for each event that is due
spawn a new php process and run it
delete the event entry so that it is not run twice
sleep(50ms)
}
如果我要将此列表存储在 MySQL 数据库中,这肯定是最好的方法,因为我需要能够使用“SELECT * FROM eventlist where duetime >= time();”行中的某些内容来查询该列表。 ,让守护进程每 50 或 100 毫秒执行一次 SELECT 是不是很疯狂?或者我只是过于偏执,服务器应该能够很好地处理它?每次迭代中检索的数据量应该相对较小,可能只有几百行,我认为它不会超过几 KB 的内存。守护进程和 MySQL 服务器也将在同一台机器上运行。
3) 如果我确实使用了上述所有内容,包括 MySQL DB 上的表,我可以做些什么来优化它?我曾考虑将表存储在内存中,但我不喜欢在服务器崩溃或重新启动时丢失其内容的想法。我能想到的最接近的事情是拥有一个完成写入和更新的标准 InnoDB 表,以及另一个执行读取的 1:1 镜像内存表。使用触发器应该可以让内存表镜像所有内容,但另一方面,维护起来确实很麻烦(如果由于某些原因表不同步,则很容易发生fubar情况)。