2015-10-15 18 views
5

मैं PHP के अंतर्निर्मित वेब सर्वर से जुड़े एक परीक्षण प्रोजेक्ट पर काम कर रहा हूं और मैं कुछ विचारों का परीक्षण कर रहा हूं।PHP अंतर्निहित वेबसर्वर कैशिंग समस्या

मैं आमतौर पर प्रयुक्त संसाधनों (पीएनजी, जेपीजी, जेसन, टीटीटी, आदि ...) के लिए अपने स्वयं के कैशिंग तंत्र को लागू करना चाहता हूं ताकि PHP में अंतर्निहित सर्वर पर लोड कम हो सके।

मैं इस तरह सर्वर में बनाया शुरू:

php एस 127.0.0.1:80 आयकर सार्वजनिक router.php

तो, के दस्तावेज़ जड़ में निर्मित सर्वर public पर सेट है और यह 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'; 

?> 

मैं निम्न URL पर जाकर reource (PNG छवि) कैशिंग परीक्षण किया:

यहाँ मेरी router.php फ़ाइल की सामग्री है http://localhost/apple-icon-120x120.png

तो, यह संसाधन के पहले लोड है, , enter image description here

अब अगर मैं Pres: तो रिटर्न HTTP 200 प्रतिक्रिया की उम्मीद के रूप में के साथ संसाधन की सेवा, लगभग 307ms लेता है F5 है पृष्ठ पुनः लोड करने, सर्वर की ओर HTTP 304 (संशोधित नहीं) के रूप में उम्मीद और अनुरोध ले लिया लगभग 5ms (महान !!): enter image description here

अगर मैं तीसरी बार के लिए F5 दबाते हैं, तो सर्वर अभी भी HTTP 304 रिटर्न (संशोधित नहीं) के रूप में उम्मीद है, लेकिन इस समय अनुरोध फिर से लगभग 306ms ले लिया (जैसे कि संसाधन कैश नहीं था): enter image description here

अगर मैं F5 दबाने रखने के लिए, समय अनुरोध पर कार्रवाई करने 5m और के बीच बेतरतीब ढंग से alternativing है लगभग 307ms

कोई विचार क्यों यह इस तरह व्यवहार कर रहा है? एक बार संसाधन कैश किए जाने के बाद, क्या यह लगातार 304 वापस नहीं लौटाएगा और अनुरोध को लगभग 5ms पर संसाधित करना चाहिए? व्यवहार sporadic क्यों है?

मुझे लगता है कि लौटाई गई सामग्री का आकार 225 bytes है (जब यह जानता है कि डेटा कैह किया गया है), तो मैं यह नहीं समझ सकता कि अनुरोध प्रक्रिया समय के साथ बाधा कहां है। मेरी मेजबान मशीन इंटेल आई 7 सीपीयू, 6 जीबी रैम & एसएसडी ड्राइव के साथ विंडोज चल रही है।

उत्तर

0

आपकी राउटर फ़ाइल ठीक काम कर रही है। मैंने इसे स्थानीय रूप से परीक्षण किया है और यह अपेक्षित व्यवहार करता है: डाउनलोड के साथ पहली बार HTTP 200, फिर केवल शीर्षलेख वाले HTTP 304।

आपकी टाइमलाइन को देखते हुए इसमें 11.9 केबी की प्रतिक्रिया देने के लिए 307 एमएस लगते हैं जो स्पष्ट रूप से बहुत धीमा है।

आपको HTTP 304 प्राप्त होता है इसलिए आपकी स्क्रिप्ट फ़ाइल भेजने के बिना बाहर निकलनी चाहिए। हालांकि, पहले उदाहरण में 304 स्टेटस कोड भेजने के लिए PHP को अभी भी mtime मिलना है और फ़ाइल के md5 हैश की गणना करना है। फ़ाइल तक पहुंच शायद बोतल-गर्दन है।

डिस्क कैशिंग के कारण 5ms और 300ms के बीच वैकल्पिक प्रतिक्रिया समय हो सकता है। शायद आपके पास हार्ड ड्राइव या हाइब्रिड ड्राइव है?

mtime से पहले और हैश गणना के बाद, शुरुआत में microtime() क्यों न गूंजें?

संबंधित मुद्दे