PHP连续检查数据库中的更改的最佳做法是什么?

yow*_*ita 6 php cron

我正在构建一个后端模块(用PHP编写),用于监视没有[完全] 300秒(5分钟)活动的私人聊天室.如果是,脚本将更新数据库(将最大用户设置为特定数量和其他内容).我通过now()和发送的最后一条消息的时差来监视空闲时间的跨度.


我做了什么:设置一个cron作业,每分钟或60秒运行(通过php-cli)我的监控脚本.在监控脚本中:

$expire_time = time() + 60;

//this loop will run for 60 seconds
while(time() < $expire_time)
{
  $idle_time = get_all_chatrooms_idle_time();
  foreach($idle_time as $s_time)
  {
    if($s_time >= 300)
    {
      update_changes();
    }
  }
  usleep(500000);
}
Run Code Online (Sandbox Code Playgroud)

在300秒空闲时间后立即设置最​​大用户的条件不能被讨价还价.所以我真的不能遵循这样的建议:"避免做任何事情直到事情要求它",即使它很有意义.

原因?活动和非活动聊天室的数据需要是实时的,因为它也将显示在仪表板上.聊天室主持人的薪水取决于它.


为什么不检查每个仪表板负载?对不起,但仍然不可能.

检查需要是服务器端,仪表板用ajax更新自己,每秒轮询一次.

当我将监控代码附加到我的ajax调用所请求的页面时,我认为它比我当前的实现更耗费资源(如果我错了,请纠正我)

让我粗略估计用户数量,以便您可以想象我们获得的负载/流量:

  • 包括主持人在内的聊天人数:~800
  • 聊天室数量:~250
  • (x)聊天室版主的数量:~50
  • (x)我的老板和他的员工:

(x) - 可以查看仪表板


有没有更好的办法?我做得对吗?

Lev*_*zél 2

这个循环太过分了。即使在中等服务器上,它也可能每分钟运行数千次,并且即使对于实时应用程序,它也会产生很高的 CPU 使用率。添加一个计数器,并查看迭代计数。我认为这会产生比处理每个 AJAX 请求更多的负载。

首先,确定您需要的信息的粒度。假设您选择3秒的粒度(例如每3秒扫描一次数据库)——这个数字对您来说可能太高了,但它说明您不会损失太多。借助 AJAX,您可以分秒必争看到一些应该连续爬升的计数器爬回一次或两次。(你是否真的会看到这样的事情取决于你的计数器的性质。)

如果您的计数器基于秒范围内的数据(例如显示经过的秒数总和,或基于美元/秒的金额),那么按秒 AJAX 拉取将不会提供连续计数器。(由于网络原因,有时会错过一秒或两次更新该秒)。

无论选择何种粒度,您的最终统计数据都会没问题,因为它们基于绝对时间戳 - 无论它们评估的时间有多晚。

如果使用秒数 AJAX 轮询来实现平滑计数器,那么您可以做得更好:计数应该在客户端运行(例如,发送带有秒数增量的值:revenue: <span data-inc="25">14432</span>并使用 JS 进行计数)。唯一实现 AJAX 来监视停止/重置计数器的情况。然后您只需确定通知可能会延迟多长时间(例如 10 秒),然后计数器将滚动最多。10秒后回落至预期值。在这种情况下,您不应更频繁地运行数据库清理(例如间隔的一半)。例如,这样可以在您的周期中睡眠 3 秒,从而大大减少负荷。

如果您可以轻松选择将每个聊天室的过期时间戳添加到数据库(记录中或固定),并使用索引,这将加快读取速度(并且还允许每个房间的过期规则)。