什么是PHP的最佳实践连续检查数据库中的更改? [英] What's the best practice for PHP to continuously check for changes in the database?

查看:91
本文介绍了什么是PHP的最佳实践连续检查数据库中的更改?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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






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

  $ expire_time = time() 

//这个循环将运行60秒
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);
}






最大用户在300秒后的空闲时间不能讨价还价。所以我不能真正关注的建议,如:避免做任何事情,直到有人真的要求它,即使它有很大的意义。



原因?活动和非活动聊天室的数据需要是实时的,因为它也将显示在仪表板上。






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



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



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



让我给大家一些粗略的估计,用户的数量,所以你可以想象我们得到的负载/流量:




  • 聊天室数量:〜800

  • 聊天室数:〜250

  • li>
  • (x)我的老板和他的工作人员:



(x) / p>




有更好的方法吗?

解决方案

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



首先,确定您需要的信息的粒度。假设你选择有3秒的粒度(例如,每3秒扫描一次数据库) - 这个数字可能太高了,但它说明你不会损失太多。随着AJAX每秒拉一次,您可能会看到一些计数器应该抓取,持续抓取一次或两次。



如果您的计数器是基于秒的范围内的数据(例如,显示经过的秒数的总和,或基于$ /秒的金额),则二次AJAX拉动将不提供连续计数器。



无论选择的粒度如何,最终的统计数据都是完全正确的,因为它们是



如果使用二次AJAX轮询来实现平滑计数器,那么比你可以做的更好:计数应该在客户端运行(例如,发送具有第二增量的值:收入:< span data-inc =25> 14432< / span> 和用JS计数)。唯一的实现AJAX来监视停止/重置计数器的条件。然后你只需要确定通知可能迟到(例如10秒),然后计数器将超过最大。 10s回落到期望值。在这种情况下,您不应该更频繁地运行DB清理(例如,一半的时间间隔)。这允许例如。



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


I am building a backend module (written in PHP) that will be used for monitoring private chat rooms that has no activity for [Exactly] 300 seconds (5 minutes). If it is, the script will update the database (sets the max users to a certain number, and other stuffs). I am monitoring the span of idle time by the time difference of now() and last message sent.


What I did: set a cron job that will run (through php-cli) my monitoring script every minute or 60 seconds. Inside the monitoring script:

$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);
}


The condition of instantly setting max users after 300 seconds idle time can't be bargained. So I cant really follow advice like: "avoid doing anything until something actually asks for it" even though it makes a lot of sense.

Reason? The data of active and inactive chatrooms need to be real time because it will also be displayed on a dashboard. The chatroom moderators' pay depends on it.


Why not check them every dashboard load? I'm sorry but still not possible.

The checking needs to be server side and the dashboard updates itself with ajax, polling every second.

When I attach the monitoring code to the page being requested by my ajax calls I think it's more resource intensive than my current implementation (correct me if Im wrong)

Let me give you some rough estimate on the number of users so you can imagine the load/traffic we're getting:

  • number of chatters including moderators: ~800
  • number of chatrooms: ~250
  • (x) number of chatroom moderators: ~50
  • (x) my boss and his staff:

(x) - can view the dashboard


Is there a better way? Am I doing it right?

解决方案

This loop is an overkill. It may run many thousand times a minute, even on a moderate server, and it generates high CPU usage even for a realtime-app. Add a counter, and see iteration count. I think this generates even more load than processing upon every AJAX request.

First of all, determine the granularity you need the information with. Suppose you choose to have 3 seconds of granularity (e.g. sweeping through the database every 3 seconds) - this number may be too high for you, but it illustrates that you don't lose much. With AJAX pulling every second you COULD see some counters that should crawl up continuously crawl back once or twice. (Whether you will really see such thing depends on the nature of your counters.)

If your counters are based on data in range of seconds (e.g. showing sums of elapsed seconds, or amounts based on $/sec) then second-wise AJAX pulling will not provide continuous counters. (It will sometimes miss a second or update to that second twice; for network reasons).

Regardless of the chosen granularity, your final statistics will be allright, because they are based on absolute timestamps - no matter how late they are evaluated.

If second-wise AJAX poll is used to implement smooth counter, than you can do much better than that: counting should run on the client side (e.g. sending values with their second-wise increment: revenue: <span data-inc="25">14432</span> and counting with JS). The only implement AJAX to monitor the condition of stopping/reseting counters. Then you only need to determine how long notification may be late (e.g. 10s) then counters will overscroll for max. 10s the drop back to the expected value. In this case you should not run DB cleanup much more often (e.g. half of the interval). That allows e.g. for a 3-second sleep in your cycle, which decreases load drastically.

If you can easily opt for adding the expiration timestamp of every chatroom to the database (either in-record or fixed) with an index that would speed up reading a bit (and additionally allow for per-room expiration rules).

这篇关于什么是PHP的最佳实践连续检查数据库中的更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆