在循环、带睡眠的循环或单独的请求中查询数据库


Querying database in a loop, loop with a sleep, or separate request

我正在考虑这三个选项,如果有任何建议,我会接受更多建议。

问题:我一直被建议放弃睡眠,我没有背景在三个之间进行选择

我一直被告知睡眠在php脚本中使用非常糟糕,但没有人强调原因。我希望这个系统是可扩展的,即这个问题的解决方案可以使用10到100倍。

选项1:睡眠

$timer = time() + (30);
while($done==0){
  $result = mysqli_query($mysqli, $query);
  $row_cnt = mysqli_num_rows($result);
  if ($row_cnt>0){
    $row = mysqli_fetch_array($result);
    print $row[0];
    $done=1;}
  else{
    $current = time();
    if( $timer>$current){sleep(1);}
    else{$done=1;}
  }

选项2:

简单地从上面去除睡眠,我的非服务器知识认为这更糟,但是,我确信我可能是非常错误的

else{
  $current = time();
  if(   $timer>$current){}
  else{$done=1;}
}

选项3:是让客户端在循环中请求页面,并让文件简单地呈现信息

$result = mysqli_query($mysqli,$query);
$row_cnt = mysqli_num_rows($result);
if ($row_cnt>0){
  $row = mysqli_fetch_array($result);
  print $row[0];

那么哪一个是最好的我的目标:

  • 可靠性最重要
  • 客户端获取信息的速度
  • 可伸缩性-重要性最低(仍然重要)

请给我一个为什么我真的想理解一种方法是优越的的说法

如果这被标记为有争议,那么这一定意味着所有答案都是有效的:)我将把它作为一个答案:)

如果你知道PHP是单线程的,它将暂停脚本其余部分的执行,那么使用PHP的睡眠并没有错。

这绝对不是"正确的做法"。当你开始连接更多的客户端时,会发生的事情是,你会有许多apache PHP线程,它们都在等待同一事件。你很快就会耗尽资源。你所做的基本上是长时间的民意调查。睡还是不睡,还是很糟糕。

更好的方法之一是使这个系统更加基于事件。当事件进入时,数据会被推送到所有客户端。根据您可用的技术,这将非常灵活,只会导致网络延迟。像WebSockets这样的东西非常适合这里。

由于您使用的是µC,无法轻松处理websocket,因此最好的做法是打开与服务器的持久TCP连接,然后直接发送数据。

下一个最好的方法是通过缓存结果(比如在memcached中)使脚本快速执行。Memcached本质上是一个内存中的键值存储。您可以使用您的clientId或唯一标识客户端的东西作为密钥。这个过程大概是这样的:

结果数据从某些外部源更新并添加到数据库中。如果数据本质上是每个客户端的,那么删除(使)memcache中该客户端的密钥,这样当它请求结果时,它就被迫直接进入数据库。如果记录结果时不是每个客户端的结果,请运行当前连接的所有客户端,并分别使其缓存无效。这个过程会很快,因为所有的东西都在RAM中。

当客户端请求结果时,脚本应该首先使用clientID作为关键字在memcache中查找,如果找不到,则查询数据库并将结果放入memcache中以备以后使用。

我手头没有任何好的memcache教程,但在谷歌上快速搜索发现了这一个,这并不糟糕:http://www.stevenmcmillan.co.uk/blog/2010/php5-memcached-example/

我还建议您重新考虑使用原始TCP套接字。你真的错过了,因为你可以在客户端和服务器之间建立实时连接,而且你的代码总体上可以更简单。如果你的主机不允许,请找一个更好的主机提供商。有这么多便宜的,如果你每月付不起5美元,我担心你的营养。我有两个atm是RamNode和DigitalOcean。

除此之外,你真的需要更详细地描述你的情况。

我将探究程序员为什么认为sleep在循环中不好,这似乎是您问题的核心。

简言之,是的,你可以利用睡眠。

那你为什么不?

理想情况下想要的是在数据库中有可用数据时做一些工作。为此,如果你能在数据可用时得到通知,那么你所做的工作就最少了。在编程中有多种方法可以实现这一点:HTTP世界中的webhook、锁/信号量、回调和事件/观察者是一些范例。另一个被引用的原因是比赛条件,我会让你读一读。由于数据库是以原子方式为您做事的,所以这并不令人担心。

然而,在理想的无状态HTTP世界中,您无法锁定,有时甚至无法获取事件或回调。我看到一些AJAX编程鼓励使用固定或随机间隔的轮询,就服务器而言,这本质上是一种睡眠形式。

你的选项2是最糟糕的,因为你的程序正在做很多无用的工作。所有这些无用的工作都会耗费你的电力,占用可能会用到其他地方的资源(CPU)。如果你登录电脑,运行任何其他程序,服务网站,所有这些都会变慢。