【问题标题】:PHP foreach loop to slow for live dashboard. What are my options?PHP foreach 循环会减慢实时仪表板的速度。我有哪些选择?
【发布时间】:2012-11-14 12:57:21
【问题描述】:

我正在使用 PHP 从呼叫中心获取大约 80 个用户的可用性数据。我希望每 5 秒向 CallCenter 查询每个用户的状态/可用性,并将结果显示在 Dashboard 上。

呼叫中心一次只能通过 URL 查询一个用户,并且用户名在 url 中(因此 url 不是恒定的)。 CallCenter 的答案在 XML 页面中。我一直在使用 fopen() 来读取 url / XML 的内容,因为这始终是随机生成的 XML 名称,因此查询 url 指向一个目录,而不是确切的 xml url。

我使用 foreach 循环来处理所有事情,其中​​唯一的 url 用于 USER001,读取 XML 页面的内容并更新变量。演示代码:

用户数组:

$users = array( 
        "username" => array("fullname" => "Full Name",
                            "status" => ""  
                            ),
        "username" => array("fullname" => "Full Name",
                            "status" => "")
                );

Foreach 循环:

foreach($users as $username => $userstatus) {
$url = 'http://'.$username.':PasswordForUser@serveraddress.com:80/callcenter/'.$username.'/services/callcenter/';
$get = fopen($url, "r");
    if ($get) {
        while (!feof($get)) {
            $status = fgets($get, 4096);
        }
        fclose($get);
    }
if(strpos($status, 'Available')) { $users[$username]["status"] = "Available"; } else { $users[$username]["status"] = "Offline"; }

}

问题:
我有一个 jquery 脚本,它每 5 秒刷新一次仪表板,因此每 5 秒都会向 CallCenter 服务器查询所有用户。

这可行,但查询实际上需要 1 多分钟才能完成循环并将所有结果返回到仪表板页面。至关重要的是,CallCenter 用户可以查看在给定时间有多少用户/代理可用,以便他们知道是否有足够的代理可用以处理 CallCenter 负载。

可能的解决方案:
对于我的情况,最好的解决方案是什么?

我想到的是为每个用户创建一个 PHP 页面。有一个 CRONJOB,每 x 小时运行一次页面(刷新),页面上有一个脚本,每 5 秒循环一次 XML 查询到 CallCenter。在每个循环结束时(每 5 秒),用户状态被发送到并更新收集器页面。每个用户页面将结果发送到收集器页面,然后仪表板页面每 5 秒将数据获取到收集器页面。

这是一个“聪明”的解决方案吗?您会推荐什么以及如何编写代码?
(我是 PHP 初学者)

【问题讨论】:

  • 查询呼叫中心需要 1 分钟?
  • @SkuliAxelson 尝试优化您的脚本,似乎 file_get_contents() 快一点 stackoverflow.com/questions/2749441/… 。也许,您可以尝试为每个用户创建一个 php 文件,并每隔 X 秒同时启动它们stackoverflow.com/questions/6577802/…
  • @SkuliAxelson 我会创建一个数据库,在数据库中放置用户的状态。我分别创建 php 文件并使用 cronjob 同时更新用户状态(类似于 status_updater.php)。另一方面,一个 php 文件 (get_status.php) 每 5 秒从数据库中解析一次用户的状态,当然 jQuery 用于获取客户端的状态。
  • @HamZa DzCyber​​DeV - 感谢 file_get_contents() 信息。我会按照你的建议尝试。有一个 DataCollector.php、AgentInfo.php,然后每 4 个用户获得一个页面,获得 4 个结果并将它们发送到 DataCollector 页面。然后仪表板包含 DataCollector 和 jquery 更新用户的统计信息。
  • @HamZaDzCyber​​DeV +1 这将充当您的数据“缓存”

标签: php xml cron


【解决方案1】:

第一次使用

echo microtime(true)

在 GET 查询之前和之后确定您从呼叫中心获得的响应速度 - 这将使您了解您的最大收益是来自 (A) 查询数量还是 (B) 速度单个查询。

如果您无法让呼叫中心更改他们的数据流程,您也将不得不走这条路线,如下所述:

线程化您的 ajax/jQuery 调用。

当您的页面刷新时 - 执行 4-6 次 ajax 调用,将线程 ID 传递给脚本, 然后溢出用户数据集合,即:80 / 4 = 每个线程 20 个用户(大多数浏览器只能处理几个 http 请求,所以不要创建太多线程,因为它们基本上会堆叠并等待一个完成 - 这不是你想要什么) - 一旦返回数据,你可以简单的 jquery 写入一个 id 即:

<div id="threadresults1"></div>
<div id="threadresults2"></div>
<div id="threadresults3"></div>
...

希望这很清楚。

【讨论】:

  • 谢谢。我使用 microtime(开始和结束)来计时 1 个用户查询。结果为 0.579805。我将研究每页大约 4 个调用的线程。前几天我尝试了 jquery,但由于这是一个跨域查询,我无法让 jquery 工作。
  • 啊,是的,这可能会造成问题,您可以使用 php get 脚本为您执行此操作,file_get_contents 可以同时发布帖子并访问任何 url。所以基本上你 ajax 一个本地脚本和本地脚本从外部 url 获取,本地 ajax 调用不应该延迟你的时间。
【解决方案2】:

由于我们在 cmets 中建立了用户列表是静态定义的并且不会以某种方式查询,因此您可以让页面知道用户列表。

然后可以为每个用户异步查询一个php页面:queryPage.php?username=john

在该页面中,您只需查询该特定用户的呼叫中心。因此,为所有 60 个用户设置 60 个异步请求而不是仅 1 个应该会对您的情况有所帮助。

【讨论】:

    【解决方案3】:

    我必须完全同意@Alexandru Mihai 在上面的评论中的观点。

    不要在 php 中运行 foreach 循环,而是将其放到 jQuery 级别,并将您的 php 脚本仅用作一对一代理。它会占用更多资源,但同时您将能够同时运行无限数量的线程/读取,因为 JS 依赖于回调,而 php 一次只需要处理一个名称。

    所以即使你的代理脚本落后了,你仍然会在 js 级别上得到其他操作员的有效响应,因此整个过程会感觉流畅且响应迅速。

    【讨论】:

      【解决方案4】:

      只是想感谢所有回复的用户。我不认为这种方法可以很好地解决我的问题,所以我按照我在最初帖子中的建议结束了。我创建了多个页面,每 1 分钟运行一个 cronjob 并收集数据。然后其他页面每 x 秒获取一次数据。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-02-20
        • 2012-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-11
        相关资源
        最近更新 更多