2

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

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

我一直被告知 sleep 在 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];

所以哪一个最好考虑我的目标:

  • 可靠性——最重要
  • 客户获取信息的速度
  • 可扩展性 - 最低重要性(仍然重要)

请告诉我为什么我真的想理解一种方法优越的说法

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

4

2 回答 2

1

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

简短的回答,是的,您可以使用睡眠。

那你为什么呢?

理想情况下,您希望在数据库中有数据时做一些工作。为此,如果您可以在数据可用时收到通知,那么您所做的工作量就最少。在编程中有多种方法可以实现这一点:HTTP 世界中的 webhook、锁/信号量、回调和事件/观察者是一些范例。另一个引用的原因是竞争条件,我将让您阅读。由于数据库正在为您自动执行操作,因此不必担心。

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

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

于 2013-07-30T01:38:46.333 回答
1

如果您了解 PHP 是单线程的并且它将暂停脚本其余部分的执行,那么使用 PHP 的 sleep 没有任何问题。

这绝对不是“正确的事情”。当您开始连接更多客户端时会发生什么,您将拥有许多 apache PHP 线程,它们都将处于休眠状态,等待同一个事件。您将很快耗尽资源。你所做的基本上是长轮询。睡不睡,还是很糟糕。

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

由于您在 µC 上并且不能轻松地使用 websocket,因此最好的办法是打开与服务器的持久 TCP 连接,然后将数据向下发送。

下一个最好的办法是通过缓存结果来使脚本快速执行,比如在memcached中。Memcached 本质上是一个内存键值存储。您将使用您的 clientId 或唯一标识客户端的东西作为键。该过程将是这样的:

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

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

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

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

除此之外,您确实需要更详细地描述您的情况。

于 2013-07-30T01:42:44.697 回答