等待时间(TTFB)超过4秒,来自`get_headers()`

时间:2015-04-04 10:38:15

标签: php

我在Windows 2012上使用Apache版本(httpd-2.4.10-win64-VC11)。我试图在点击图像项目时执行此操作,它将打开有关此项目的信息的对话框。我这样做:

var self = $(this),
  vaid = "1",
  btnhref = self.attr('href'),
  itemID = getVar("item",btnhref);

$.ajax({
  type: 'POST',
  url: '/action.php',
  data: {"itemID" : itemID},
  dataType: 'json',
  beforeSend: function(xhr) {                     
    xhr.setRequestHeader('va', vaid);                                  
  },
  statusCode: {
    401:function() { Validation('401 Unauthorized</br>Error: Invalid Action'); }
  },
  complete: function()
  {       
    var state = {
      "dialog": true
    };
    history.pushState(state, document.title, btnhref);                              
  },
  success: function(response){},
  cache: true,
  contentType: "application/x-www-form-urlencoded",
  processData: true
});

问题是响应非常缓慢,我无法找到原因。下面我添加从chrome speed tracer收到的数据。

P.S:我正在使用cloudfront for images,CSS&amp; Javascripts文件。

http://i.stack.imgur.com/UEh2Q.png

编辑:来自fiddler web调试器的详细信息:(使用GET或POST相同的结果)

==时间信息============

ClientConnected:13:53:10.037

ClientBeginRequest:13:53:10.064

GotRequestHeaders:13:53:10.064

ClientDoneRequest:13:53:10.064

确定网关:0ms

DNS查询:1毫秒

TCP / IP连接:16毫秒

HTTPS握手:0ms

ServerConnected:13:53:10.080

FiddlerBeginRequest:13:53:10.080

ServerGotRequest:13:53:10.080

ServerBeginResponse:13:53:10.593

GotResponseHeaders:13:53:10.593

ServerDoneResponse:13:53:15.366

ClientBeginResponse:13:53:15.366

ClientDoneResponse:13:53:15.366

Apache Log:LogFormat“%h%l%u%t \”%r \“%&gt; s%b \”%{Referer} i \“\”%{User-Agent} i \ “”合并

37.8.80.203 - - [04/Apr/2015:11:06:13 +0000] "GET /shadiCo/item/146 HTTP/1.1" 200 33640 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"
37.8.80.203 - - [04/Apr/2015:11:06:20 +0000] "POST /method/pusher HTTP/1.1" 200 96 "http://localhost/shadiCo/item/146" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"
37.8.80.203 - - [04/Apr/2015:11:06:20 +0000] "POST /method/pusher HTTP/1.1" 200 96 "http://localhost/shadiCo/item/146" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"

使用后编辑@elcodedocle代码: 问题不是ajax或mysql问题,它的get_headers()函数问题会减慢我用来检查图像是否存在的请求,使用此函数:

public function url_exists($url) {
    if(!empty($url) && $this->is_url($url) && extension_loaded('openssl'))
    {              
            $file_headers = get_headers($url);
            if($file_headers[0] == 'HTTP/1.1 404 Not Found')
            {
              return false;
            }else{

                    $allowed = array('Content-Type: image/jpeg','Content-Type: image/pjpeg','Content-Type: image/png','Content-Type: image/gif');

                     if(!in_array($file_headers[1], $allowed))
                     {
                                    return false;
                     }else{
                                    return true;
                     }                     
             }  
   }else{
        return false;
   }
}

1 个答案:

答案 0 :(得分:0)

您似乎没有客户端延迟问题,既不构建和发送请求也不处理结果。

您应该开始查看服务器上发生了什么。

  • 您的服务器端脚本是否立即开始执行?检查浏览器发送请求和脚本执行开始之间没有明显延迟。 Web服务器路由或某种其他类型的服务器配置错误可能会延迟脚本执行的开始。

  • 你的脚本哪个部分正在放慢速度?您必须通过使用断点来确定延迟的位置(Xdebug将帮助您),这是实现它的专业方法,或者通过在不同点记录服务器的时间戳(在我的意见更加业余,但更简单的一次解决方案),例如使用microtimeerror_log

<?php

// Execution starts (compare this timestamp with the browser's request timestamp to check for delays on execution start)

ob_start();

$opNames = array();
$opDelays = array();
$start = microtime(true);
error_log("Start time: {$start}");
$time = $start;

// Initialization, read and process input ops, etc ...

// YOUR CODE HERE

$prevtime = $time;
$time = microtime(true);
$delay = $time - $prevtime;
$opNames[] = "Input processing";
$opDelays[] = $delay;
error_log("Input processed at {$time}. Processing time: {$delay}");

// Database access

// YOUR CODE HERE

$prevtime = $time;
$time = microtime(true);
$delay = $time - $prevtime;
$opNames[] = "Database access";
$opDelays[] = $delay;
error_log("Database response received at {$time}. Operation duration: {$delay}");

// Results processing, output formatting...

// YOUR CODE HERE

$prevtime = $time;
$time = microtime(true);
$delay = $time - $prevtime;
$opNames[] = "Results processing";
$opDelays[] = $delay;
error_log("Results processed at {$time}. Processing time: {$delay}");

// Output flushing and end of execution

ob_end_flush();

$time = microtime(true);
$delay = $time - $start;
$maxDelayIndexes = array_keys($opDelays, max($opDelays));
error_log("End of script execution at {$time}. Total processing time: {$delay}. Most expensive operation: ".$opNames[$maxDelayIndexes[0]]);
  • 你如何解决这个问题?当你知道问题是什么时再问一次。

<强> [编辑]

因此,您已对脚本进行了分析,发现get_headers($url)正在减慢执行速度。

您想检查$url

上是否存在特定的公共资源(图像)

这真的是一个远程资源还是托管在运行应用程序的同一台服务器上?因为如果它是本地的,那么简单的file_exists($_SERVER['DOCUMENT ROOT']."path/to/my/image.jpg")就可以做到,并且比完整的HTTP请求get_headers($url)执行的速度快几个数量级。

如果它是位于不同服务器上的远程资源,您仍然可以通过使用PHP curl extension来加速该过程,这允许&#34; ping&#34;获取响应代码的资源,无需等待接收完成(在重图像上,它甚至可能超过您遇到问题的4秒)。这就是它的完成方式:

public function url_exists($url){
  if(empty($url) || !$this->is_url($url)){
    return false;
  }
  $curl = curl_init();
  curl_setopt_array( $curl, array(
      CURLOPT_RETURNTRANSFER => true, // get result as a string, do not output
      CURLOPT_URL => $url, // url to connect to
      CURLOPT_NOBODY => true, // only the header
      CURLOPT_SSL_VERIFYPEER => false, // we don't really care about cert validation for this, do we?
      CURLOPT_CONNECTTIMEOUT => 2 // return error if can't connect in 2 seconds or less
    ) 
  );
  curl_exec( $curl );
  $response_code = curl_getinfo( $curl, CURLINFO_HTTP_CODE );
  curl_close( $curl );
  if ($response_code === 200){
    return true;
  }
  return false;
}

在旁注中,如果您仍然遇到性能问题,您可能有兴趣浏览other cURL options,例如DNS缓存过期时间,以加快DNS解析速度,这通常是检查的缓慢部分当服务器IP未缓存时。