我有一个PHP脚本,它从外部服务中获取数据并将数据保存到我的数据库中。我需要这个脚本每分钟为系统中的每个用户运行一次(我期望成千上万)。我的问题是,每分钟运行每个用户最有效的方法是什么?起初我以为我会有一个函数从我的数据库中抓取所有用户ID,遍历id并为每个用户执行任务,但我认为随着用户数量的增长,这将需要更长时间,而不再间隔1分钟。也许我应该排队用户ID,并为每个人单独执行任务?在这种情况下,我实际上不确定如何继续。
提前感谢任何建议。
修改
回答Oddthinking的问题:
我想同时为每个用户启动流程。当每个用户的过程完成时,我想等待1分钟,然后再次开始该过程。所以我想每个用户的每个进程都应该是异步的 - 用户1的进程不应该关心用户2的进程。
回答sims的问题:
我无法控制外部服务,外部服务的用户与我的数据库中的用户不同。我担心我不知道任何其他脚本语言,所以我需要使用PHP来做到这一点。
答案 0 :(得分:2)
我是否正确总结?
您希望每分钟执行数千项任务,但您不确定是否可以及时完成这些任务?
您需要决定何时开始按计划运行。
这些问题的答案取决于申请。根据答案,Cron可能不适合您。您可能最好让流程永久运行并自行安排。
答案 1 :(得分:1)
所以,让我直截了当地说:你每分钟都在为数据库中的每个用户查询一个外部服务(什么是SOAP?MYSQL?),并将结果存储在同一个数据库中。这是对的吗?
这似乎是一个设计问题。
如果外部服务上的用户与数据库中的用户相同,则两者应该更紧密地配置。我不知道PHP是否是同步这些数据的方法。如果你提供更多细节,我们可以考虑另一个解决方案。如果您控制外部服务,您可能希望让该服务转储它的数据,甚至直接写入数据库。其他一些同步机制可能更好。
修改
您似乎正在创建一个为用户存储数据的应用程序,然后可以按时间顺序查看。否则,您也可以在用户请求时获取数据。
在go中获取所有用户ID。
逐个迭代它们(假设所提取的数据对每个用户来说都是唯一的)并且(因为PHP线程不存在AFAIK,你必须在这里创造)为每个请求调用一个进程如果一个用户没有返回数据,你希望它们全部同时执行而不会延迟。
所述进程应在返回后立即将返回的数据插入到数据库中。
至于cron是否适合这项工作:只要你拥有一台足够强大的服务器,可以同时处理数以千计的上述cron作业,你应该没问题。
您可以通过多个PHP脚本获得创意。我不确定,但如果每个CLI调用PHP都启动一个新的PHP进程,那么你可以这样做。
foreach ($users as $user)
{
shell_exec("php fetchdata.php $user");
}
这一切都非常沉重,你不应该期望用PHP做得很好。做一些测试。不要相信我的话。
答案 2 :(得分:1)
数据库可以立即处理BULKS记录。如果您正在逐个处理它们,那么您正在寻找麻烦。您需要找到批量处理“每分钟”任务的方法,以便通过执行SINGLE(复杂)查询,检索所有受影响的用户信息;那么,你会对结果进行PHP处理;然后,在另一个查询中,您将结果推回到数据库中。
答案 3 :(得分:1)
根据你的大图描述,听起来你有一个死胡同的设计。如果你能够立即使用它,它很可能非常脆弱,根本不会扩展。
我猜测如果你无法控制外部服务,那么外部服务可能不会因为你的脚本受到这样的打击而感到高兴。你有没有按照总体计划与他们联系?
你真的需要每次都做所有用户吗?是否有任何时间戳可用于更具选择性地关注哪些用户需要“更新”?也许如果你能够更好地描述目标,我们可以提供更具体的建议。
答案 4 :(得分:1)
鉴于您想要同时运行用户处理......
跳出来的最简单的解决方案是每个用户拥有一个线程。在Windows上,线程比进程便宜得多。
但是,无论您使用线程还是进程,同时运行数千个几乎肯定是行不通的。
相反,拥有一个池的线程。池的大小取决于您的机器一次可以轻松处理的线程数。我希望30-150这样的数字可以达到您想要的范围,但这在很大程度上取决于硬件的容量,而且我可能会超出另一个数量级。
每个线程都会抓取下一个用户,因为它是从共享队列中处理的,处理它,并将其放回队列的末尾,可能是一个不应该处理它的日期。
(根据处理的数量和类型,这可以在数据库的单独框中完成,以确保数据库不会因非数据库相关处理而过载。)
此解决方案可确保您始终尽可能多地处理用户,而不会使计算机过载。随着用户数量的增加,处理频率会降低,但总是和硬件允许的一样快。