无限循环中的进程队列

process queues in infinite loop

提问人:morgi tmr dasdas 提问时间:10/19/2023 最后编辑:morgi tmr dasdas 更新时间:10/21/2023 访问量:154

问:

我们有一个在线PHP游戏,需要每秒处理一次任务,我们目前正在通过命令curl -s每分钟运行一个cron作业到我们的某些脚本,以便通过循环一整分钟来每秒处理一些任务,超时60秒。

该方法我们面临 2 个问题:

1-有时查询需要超过1分钟,这会导致数据丢失,因为超时 2- 如果我们删除超时,那么有时我们会遇到高 CPU 问题

它肯定是第二,游戏主要是基于此。

我们目前的代码是:

set_time_limit(65);
  for ($i = 0; $i < 59; ++$i){
  $this->doThings();
  sleep(1);
 }

我正在考虑使用 while 而不是 for 来 100% 准确地计算时间,这样更好吗?

任务通常不繁重,我们的 quires 尽可能地优化。

我尝试增加超时限制,并尝试增加 mysql cnf 中的net_write_timeout,这似乎很好地解决了这个问题,但使 cpu 过载问题。

我需要一种正式的方式来每秒处理我们的任务,而不会丢失任何数据或创建过载的 cpu..

##UPDATE

游戏是关于战争之类的东西,当玩家A攻击玩家B时,系统计算出的2个村庄之间会有一段距离,假设是5分钟。

然后它将存储在数据库中,表格 end_time = 现在 + 5 分钟,

所以 $this->doThings() 将从 db 调用应该现在执行的队列 (end_time = now or less ),然后按它们的类型循环它们以进行相应的处理。

我的意思是“接管 1 分钟”我的意思是整个 cron 任务而不是一项任务,对不起解释不好。

当一个 cron 占用 1 分钟以上时,意味着最后一个队列我丢失了,如果我们增加超时,那么就会重叠并导致 CPU 重叠。

##UPDATE 2

这个代码更好吗?

$timelimit = 59; //seconds
set_time_limit($timelimit + 1);
$start_time = time(); //set startup time;

while(((time() - $start_time) < $timelimit) || !$timelimit){
    $this->doThings();
}
php mysql apache cpu

评论

2赞 user1191247 10/19/2023
如果没有对整个应用程序的详细信息和理解,就不可能发表评论。$this->doThings();
3赞 Martin Bean 10/19/2023
PHP真的不是网络游戏背景的最佳选择。无论如何,如果您有需要处理的消息,为什么不使用实际的队列呢?将消息推送到队列,并具有持续处理这些消息的队列守护程序。
1赞 user1191247 10/19/2023
不要使用 cron 通过 curl 调用脚本。使用 PHP cli 运行脚本,以避免 Web 服务器不必要的开销。为什么“有时查询需要 1 分钟以上”
0赞 Sammitch 10/20/2023
1. 您可能不需要在后台不断运行代码,只需在当前请求和先前请求之间留出时间,然后计算这段时间内发生的事情。2. 如果您仍然需要一般的服务器刻度,那么它们可能会存在于 cron 的 1+ 分钟时间范围内。3. 如果你在 X 的时间间隔上运行代码,并且需要 >X 才能完成,你就不能用手挥舞你的方式。要么优化代码,要么添加资源,要么分解工作。4. 在某种程度上,PHP只是持久守护进程和/或多线程应用程序的错误选择。
0赞 morgi tmr dasdas 10/20/2023
问题是整个应用程序已经建立在 PHP 上,有现场播放器。切换到另一种语言是我目前负担不起的选择..现在我面临当前代码的问题,数据要么在超时期间丢失,要么被同时工作的 2 个 cron 作业加倍(另一个开始,而第一个尚未完成....)我如何至少确保另一个 cron 不会启动,直到第一个完成,并且在超时期间不会引起任何问题?

答: 暂无答案