【问题标题】:Why does this code so negatively affect my server's performance?为什么这段代码会对我的服务器性能产生如此负面的影响?
【发布时间】:2015-10-13 03:47:42
【问题描述】:

我有一个处理非常大数据的 Silverstripe 网站。我创建了一个返回非常大的转储的 API,并在前端通过 ajax get 调用该 API。

当 ajax 调用 API 时,需要 10 分钟才能返回数据(很长的 json 数据并且客户接受了)。

当他们等待数据返回时,他们在另一个选项卡中打开同一个站点来做其他事情,但是在前一个 ajax 请求完成之前,该站点非常慢。

我能做些什么来避免在等待大 json 数据时一切都没有响应?

这是代码及其作用的解释:

我创建了一个名为geteverything 的方法,它驻留在下面的Web 服务器上,它访问另一个服务器(数据服务器)以通过流API(位于数据服务器中)获取数据。数据量大,数据服务器慢;我的客户不介意请求需要很长时间,他们介意其他一切变得多么缓慢。会话用于确定请求的细节。

protected function geteverything($http, $id) {
    if(($System = DataObject::get_by_id('ESM_System', $id))) {
        if(isset($_GET['AAA']) && isset($_GET['BBB']) && isset($_GET['CCC']) && isset($_GET['DDD'])) {
            /**
              --some condition check and data format for AAA BBB CCC and DDD goes here
            **/
            $request = "http://dataserver/streaming?method=xxx";
            set_time_limit(120);
            $jsonstring = file_get_contents($request);
            echo($jsonstring);
        }
    }
}

我该如何解决这个问题,或者您还需要知道什么才能提供帮助?

【问题讨论】:

  • 一旦file_get_contents() 完成,$jsonstring 有多大?以较小的(例如 512 个字符)块的形式阅读可能值得一读,边写边写到浏览器中,因此您永远不会将 整个 转储存储在内存中。另外,数据的字符集是什么?您必须与多字节字符抗衡吗?
  • 感谢您修复我的英语 Tim :)
  • 对,但它有多大?例如。 strlen($jsonstring) - 我很好奇 $jsonstring 占用多少 RAM file_get_contents() 完成。可能值得使用fsockopen(),一次只读取 1k,然后在循环中将其写入浏览器。目前,您将其全部存储在内存中,然后将其写入浏览器,这可能是您速度变慢的原因。
  • 数据多久变化一次,你能每天获取它并缓存它吗?或者,在早上 8 点和下午 5 点期间,有一个进程每 15 分钟获取一次并保持它自己是最新的?也许限制您返回的数量,获取最新的 50 行,如果他们想要更多,请再获取 50 行等。
  • @Wizzard,见上面的代码,是的,它正在从另一个服务获取一个大流并返回它。肯定可以直接链接到该流,除非该流无法从外部访问或该程序必须充当代理。

标签: php ajax silverstripe


【解决方案1】:

花费这么长时间的原因是您将整个 json 下载到您的服务器,然后将其全部发送给用户。在开始发送之前,无需等待您获取整个文件。

而不是使用file_get_contents 与 curl 建立连接并将输出直接写入php://output

例如,此脚本将完全按原样复制http://example.com/

<?php

    // Initialise cURL. You can specify the URL in curl_setopt instead if you prefer
    $ch = curl_init("http://example.com/");

    // Open a file handler to PHP's output stream
    $fp = fopen('php://output', 'w');    

    // Turn off headers, we don't care about them
    curl_setopt($ch, CURLOPT_HEADER, 0);

    // Tell curl to write the response to the stream
    curl_setopt($ch, CURLOPT_FILE, $fp);

    // Make the request
    curl_exec($ch);

    // close resources
    curl_close($ch);
    fclose($fp);

【讨论】:

    猜你喜欢
    • 2014-07-02
    • 2011-03-15
    • 1970-01-01
    • 2011-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-18
    • 1970-01-01
    相关资源
    最近更新 更多