等待时间(TTFB)高于“get_headers()”的4秒结果


Waitting Time ( TTFB ) is above 4 seconds result from `get_headers()`

我在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速度跟踪器收到的数据。

附言:我正在使用cloudfront的图像,CSS&Javascript文件。

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

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

===定时信息=============

客户端连接时间:13:53:10.037

ClientBeginRequest:13:53:10.064

GotRequestHeaders:13:53:10.064

ClientDone请求:13:53:10.064

确定网关:0ms

DNS查找:1ms

TCP/IP连接:16ms

HTTPS握手:0ms

服务器连接时间:13:53:10.080

FiddlerBeginRequest:13:53:10.080

ServerGot请求:13:53:10.080

服务器开始响应:13:53:10.593

GotResponseHeaders:13:53:10.593

服务器完成响应:13:53:15.366

ClientBeginResponse:13:53:15.366

ClientDone回复:13:53:15.366

Apache日志:LogFormat"%h%l%u%t''"%r''"%>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;
   }
}

您似乎没有客户端延迟的问题,无论是构建和发送请求还是处理结果。

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

  • 服务器端脚本是否立即开始执行?请检查浏览器发送请求的时刻与脚本执行开始的时刻之间是否存在显著延迟。Web服务器路由或其他类型的服务器错误配置可能会延迟脚本执行的开始。

  • 你剧本的哪一部分放慢了速度?您必须通过使用断点(Xdebug将帮助您)来确定延迟的位置,这是专业的方法,或者通过记录服务器在不同点的时间戳(在我看来,这更业余,但更简单的一次性解决方案),例如使用microtime和error_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]]);
  • 你怎样才能解决这个问题?当你知道问题出在哪里时再问一次

[EDIT]

因此,您分析了您的脚本,发现get_headers($url)是减慢执行速度的原因。

您想检查$url 上是否存在特定的公共资源(图像)

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

如果它是位于另一台服务器上的远程资源,您仍然可以通过使用PHP curl扩展来加快进程,该扩展允许"ping"资源以获得响应代码,而无需等待接收完成(在重图像上,这可能比您遇到问题的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;
}

顺便说一句,如果您在这方面仍然存在性能问题,您可能有兴趣探索其他cURL选项,如DNS缓存过期时间,以加快DNS解析,当服务器IP未缓存时,这通常是检查的缓慢部分。