2015-10-15 43 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()