2015-10-15 38 views
5

Tôi đang làm việc trên một dự án thử nghiệm liên quan đến máy chủ web được xây dựng trong PHP và tôi đang thử nghiệm một số ý tưởng.php được xây dựng trong máy chủ web caching vấn đề

Tôi muốn triển khai cơ chế lưu bộ nhớ cache của riêng mình cho các tài nguyên thường được sử dụng (png, jpg, json, txt, v.v ...) để giảm tải trên máy chủ tích hợp trong php.

tôi bắt đầu xây dựng trong máy chủ như thế này:

php -S 127.0.0.1:80 -t router.php công

Vì vậy, các tài liệu gốc của built-in máy chủ được đặt thành public và nó chạy router.php (vì tôi cũng đang nghĩ đến việc triển khai tính năng viết lại đơn giản).

Dưới đây là nội dung của tập tin router.php tôi:

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

?> 

Tôi đã thử nghiệm reource (png) bộ nhớ đệm bằng cách truy cập địa chỉ sau đây: http://localhost/apple-icon-120x120.png

Vì vậy, đây là tải đầu tiên của tài nguyên, để phân phát trả lại tài nguyên với phản hồi HTTP 200 như mong đợi, mất khoảng 307ms: enter image description here

Bây giờ, nếu tôi đặt trước s các F5 để tải lại trang, máy chủ trả HTTP 304 (không thay đổi) như mong đợi và yêu cầu mất khoảng 5ms (tuyệt vời !!): enter image description here

Nếu tôi nhấn F5 lần thứ ba, máy chủ vẫn trả HTTP 304 (không thay đổi) như mong đợi, tuy nhiên thời gian này yêu cầu mất khoảng 306ms một lần nữa (như nếu tài nguyên không được cache): enter image description here

Nếu tôi tiếp tục nhấn F5, thời gian để xử lý yêu cầu được alternativing ngẫu nhiên giữa 5m và khoảng 307ms.

Bất kỳ ý tưởng nào tại sao nó hoạt động như thế này? Khi tài nguyên được lưu vào bộ nhớ cache, không nên nó liên tục trả lại 304 và xử lý yêu cầu xấp xỉ 5ms? Tại sao hành vi rời rạc?

Tôi thấy rằng kích thước nội dung trả về là 225 bytes (khi biết dữ liệu được xác định), tôi không thể tìm ra nơi nút cổ chai có thời gian xử lý yêu cầu. Máy chủ của tôi đang chạy các cửa sổ với CPU Intel i7, ổ cứng 6GB RAM & SSD.

Trả lời

0

Tệp bộ định tuyến của bạn hoạt động tốt. Tôi đã thử nghiệm nó cục bộ và nó hoạt động như mong đợi: lần đầu tiên HTTP 200 với tải xuống, sau đó là HTTP 304 chỉ với tiêu đề.

Nhìn vào dòng thời gian của bạn phải mất 307 mili giây để phục vụ phản hồi 11,9 KB rõ ràng là quá chậm.

Bạn nhận được HTTP 304 để tập lệnh của bạn phải được thoát mà không gửi tệp. Tuy nhiên, để gửi mã trạng thái 304 trong trường hợp đầu tiên, PHP vẫn phải tìm số mtime và tính giá trị băm md5 của tệp. Truy cập tập tin có lẽ là cổ chai.

Thời gian phản hồi xen kẽ giữa 5ms và 300ms có thể do bộ nhớ đệm đĩa gây ra. Có lẽ bạn có một ổ đĩa cứng hoặc một ổ đĩa lai?

Tại sao không lặp lại microtime() khi bắt đầu, trước mtime và sau khi tính toán băm?

Các vấn đề liên quan