PHP内置Web服务器缓存问题

5
我正在进行一个测试项目,涉及到PHP内置的Web服务器,并且我正在测试一些想法。
我想为常用资源(如png、jpg、json、txt等)实现自己的缓存机制,以减少在PHP内置服务器上的负载。
我这样启动内置服务器: php -S 127.0.0.1:80 -t public 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';

?>

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

首次加载资源时,服务器返回预期的HTTP 200响应,大约需要307msenter image description here

现在,如果我按下F5重新加载页面,则服务器返回预期的HTTP 304(未修改),请求大约需要5ms(很好!!): enter image description here

如果我第三次按下F5,服务器仍然返回预期的HTTP 304(未修改),但是这次请求再次需要大约306ms(就像资源没有被缓存一样): enter image description here

如果我继续按下F5,处理请求的时间会在5ms和大约307ms之间随机交替。

有什么想法为什么会这样?一旦资源被缓存,它不应该始终返回304并处理请求大约需要5ms吗?为什么行为是断断续续的?

我看到返回的内容大小为225字节(当它知道数据已被缓存时),我只是无法弄清楚请求处理时间的瓶颈在哪里。我的主机使用Windows操作系统,Intel i7 CPU,6GB RAM和SSD驱动器。

1个回答

0

你的路由器文件运行良好。我已经在本地测试过了,它的表现符合预期:第一次HTTP 200下载,然后只有头部的HTTP 304。

从你的时间轴来看,提供11.9 KB响应需要307毫秒,这显然太慢了。

你确实收到了HTTP 304,因此你的脚本必须在发送文件之前退出。但是,为了在第一次发送304状态码时PHP仍然必须找到mtime并计算文件的md5哈希值。访问文件可能是瓶颈所在。

响应时间在5ms和300ms之间交替可能是由于磁盘缓存引起的。也许你有一个硬盘或混合驱动器?

为什么不在mtime之前和哈希计算之后,在开始时输出microtime()呢?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接