2015-10-15 9 views
5

私はPHPの組み込みWebサーバーに関連するテストプロジェクトに取り組んでおり、いくつかのアイデアを試しています。PHPに組み込まれたWebサーバーのキャッシュ問題

一般的に使われているリソース(png、jpg、json、txtなど)に独自のキャッシュメカニズムを実装して、PHPの組み込みサーバーの負荷を軽減したいと考えています。

私はこのようなサーバーで構築を開始:

PHPは、だから、ビルトインサーバーのドキュメントルートを127.0.0.1:80 -t公共router.php

を-S publicに設定され、router.phpが実行されます(単純な書き換え機能を実装することも考えています)。 、http://localhost/apple-icon-120x120.png

だから、これはリソースの最初の負荷は次のとおりです。

<?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'; 

?> 

は、私は次のURLにアクセスしreource(PNG画像)キャッシュをテストした:

は、ここに私のrouter.phpファイルの内容です 今enter image description here

、I PRES場合:期待、約307msを取るようにHTTP 200応答を返しますリソースを提供ページをリロードするF5をsの予想通り、サーバは(変更されません)HTTP 304返し、要求が(!!素晴らしい)約5msました: enter image description here

私は三度目のF5を押すと、サーバーはまだHTTP 304を返します。予想通り、(リソースがキャッシュされていなかったかのように)要求が再び約306msましたが、この時間は(変更されません):私はF5を押し続けると、要求を処理する時間が5mとの間でランダムにalternativingさ enter image description here

307ms

これがこのように動作する理由は何ですか?リソースがキャッシュされると、それは常に304を返して、要求を約5msに処理してはいけませんか?行動が散発的なのはなぜですか?

返されるコンテンツのサイズが225 bytesであることがわかりました(データが認識されているとわかっています)、リクエスト処理時間のどこにボトルネックがあるのか​​分かりません。私のホストマシンはIntel i7 CPU、6GB RAMのWindowsを実行しています& SSDドライブ。

答えて

0

ルータファイルが正常に動作しています。私はそれをローカルでテストして、期待通りに動作します。最初にHTTP 200をダウンロードし、次にHTTP 304にヘッダーのみを置きます。

あなたのタイムラインを見ると、明らかに遅すぎる11.9 KBの応答を提供するのに307ミリ秒かかります。

HTTP 304を受信するので、スクリプトをファイルを送信せずに終了する必要があります。しかし、最初のインスタンスで304ステータスコードを送信するには、PHPはまだmtimeを見つけて、ファイルのmd5ハッシュを計算する必要があります。おそらくファイルへのアクセスはボトルネックです。

ディスクキャッシングによって応答時間が5msから300msの間で交互に発生する可能性があります。多分あなたはハードドライブかハイブリッドドライブを持っていますか?

microtime()を最初に、mtimeの前とハッシュ計算後にエコーしないのはなぜですか?

関連する問題