Я работаю над тестовым проектом с использованием встроенного веб-сервера PHP, и я тестирую некоторые идеи.php встроенная проблема кэширования веб-сервера
Я хочу реализовать свой собственный механизм кеширования для широко используемых ресурсов (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
ответ, как ожидается, займет около 307ms
:
Теперь, если прес I вляется F5
перезагрузить страницу, сервер возвращает HTTP 304
(не изменяется), как и ожидалось, и запрос занял около 5ms
(здорово !!):
Если я нажимаю F5
в третий раз, сервер по-прежнему возвращает HTTP 304
(не изменяется), как и ожидалось, однако на этот раз запрос занял около 306ms
снова (как если ресурс не кэшируются):
Если я продолжать нажимать F5
, время обработки запроса является alternativing случайным между 5m
и приблизительно 307ms
.
Любые идеи, почему это так? Как только ресурс будет кэширован, он должен постоянно возвращать 304
и обрабатывать запрос приблизительно 5ms
? Почему поведение спорадическое?
Я вижу, что размер возвращаемого содержимого равен 225 bytes
(когда он знает, что данные привязаны), я просто не могу понять, где узкое место с временем обработки запроса. Мой хост-компьютер работает с окнами с процессором Intel i7, 6 ГБ оперативной памяти & SSD-накопителями.