2015-10-15 42 views
5

我正在开发一个涉及PHP内置web服务器的测试项目,我正在测试一些想法。php内置的web服务器缓存问题

我想实现我自己的常用资源(png,jpg,json,txt等...)的缓存机制,以减少内置服务器在php中的负载。

我开始内置的服务器是这样的:

PHP -S 127.0.0.1:80 -t公共router.php

所以,文档根内置服务器设置为public,它运行router.php(因为我正在考虑实现一个简单的重写功能)。

这是我的router.php文件的内容:

<?php 

// Register request uri 
$requestUri = isset($_SERVER['REQUEST_URI']) 
    ? $_SERVER['REQUEST_URI'] 
    : '/'; 

// Handle app resources with caching 
if (preg_match('/\.(?:png|jpg|jpeg|gif|xml|json|css|eot|svg|otf|ttf|woff|woff2|scss|less|txt|ico)$/', $requestUri)) 
{ 
    // Generate file name 
    $fileName = __DIR__ .'/public'. $requestUri; 

    // Parse file data 
    $lastModified = filemtime($fileName); 
    $etagFile = md5_file($fileName); 
    $ifModifiedSince = (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false); 
    $etagHeader = (isset($_SERVER['HTTP_IF_NONE_MATCH']) ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : false); 

    // Set caching header 
    header('Last-Modified: '. gmdate('D, d M Y H:i:s', $lastModified) .' GMT'); 
    header('Etag: '. $etagFile); 
    header('Cache-Control: public'); 

    // Check if the requested resource has changed 
    if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModified || $etagHeader == $etagFile) 
    { 
     // File has not changed 
     header('HTTP/1.1 304 Not Modified'); 
     exit; 
    } 
    else 
    { 
     // Parse requested resource's mime type 
     $finfo = new finfo(FILEINFO_MIME); 
     $mime_type = $finfo->buffer(
      file_get_contents($fileName, false, null, -1, 64), 
      FILEINFO_MIME_TYPE 
     ); 

     // Serve requested resource 
     header('Content-Type: '. $mime_type); 
     header('Content-Length: '. filesize($fileName)); 
     @readfile($fileName); 
     $finfo = null; 
     exit; 
    } 
} 

// Parse requested page & action 
list ($page, $action) = 
    array_pad(array_values(array_filter(explode('/', $requestUri, 3), 'strlen')), 2, 'index'); 
if ($page == 'index') $page = 'server'; 

// Test - to do rest of routing 
var_dump('page = '. $page); 
var_dump('action = '. $action); 
// include 'app/'. $page .'/'. $action .'.php'; 

?> 

我通过访问以下网址测试reource(PNG图像)缓存:http://localhost/apple-icon-120x120.png

所以,这是资源的第一负载,所以服务回报与预期HTTP 200响应的资源,需要约307msenter image description here

现在,如果我PRES S中的F5重新加载页面,服务器返回HTTP 304(不修改)如预期,并且请求了约5ms(伟大的!): enter image description here

如果我按F5第三次,服务器仍然返回HTTP 304 (不修改)如预期,不过这一次的请求大约306ms了一次(好像是资源没有缓存): enter image description here

如果我硬逼F5,处理请求的时间是随机5m之间alternativing约307ms

任何想法,为什么它的行为是这样的?一旦资源被缓存,不应该不断地返回304并处理请求约5ms?为什么零星的行为?

我确实看到返回的内容大小为225 bytes(当它知道数据已被封装)时,我无法弄清楚请求处理时间的瓶颈在哪里。我的主机运行带有Intel i7 CPU,6GB RAM & SSD驱动器的Windows。

回答

0

你的路由器文件工作正常。我已经在本地进行了测试,它的行为如预期的那样:第一次下载HTTP 200,然后是只有头文件的HTTP 304。

看着你的时间线需要307毫秒来响应11.9 KB,这显然太慢了。

您确实收到HTTP 304,因此您的脚本必须已经退出而不发送该文件。但是,在第一次发送304状态码时,PHP仍然需要找到mtime并计算文件的散列值。访问该文件可能是一个瓶颈。

响应时间在5ms到300ms之间变化可能由磁盘缓存引起。也许你有硬盘驱动器或混合驱动器?

为什么不在开始时,在mtime之前和散列计算之后回显microtime()