Sto lavorando a un progetto di test che coinvolge il web server integrato di PHP e sto testando alcune idee.problema di caching del webserver integrato in php
Desidero implementare il mio meccanismo di caching per le risorse di uso comune (png, jpg, json, txt, ecc.) Per ridurre il carico sul server integrato in php.
comincio il costruito nel server in questo modo:
php -S 127.0.0.1:80 router.php pubblico -t
Così, la radice del documento del server incorporato è impostato su public
ed esegue lo router.php
(poiché sto pensando di implementare anche una semplice funzione di riscrittura).
Ecco il contenuto del mio file 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';
?>
Ho testato il reource (immagine png) caching visitando il seguente URL: http://localhost/apple-icon-120x120.png
Quindi, questo è il primo carico della risorsa, in modo da servire ritorna la risorsa con HTTP 200
risposta come previsto, prende circa 307ms
:
Ora, se io pres s il F5
a ricaricare la pagina, il server restituisce HTTP 304
(non modificati) come previsto e la richiesta sono voluti circa 5ms
(grande !!):
Se premo F5
per la terza volta, il server restituisce ancora HTTP 304
(non modificati) come previsto, ma questa volta la richiesta sono voluti circa 306ms
di nuovo (come se la risorsa non è stata memorizzata nella cache):
Se continuo premendo F5
, il tempo per elaborare la richiesta è alternativing casualmente tra 5m
e circa 307ms
.
Qualche idea sul perché si comporta in questo modo? Una volta che la risorsa è stata memorizzata nella cache, non dovrebbe restituire costantemente 304
ed elaborare la richiesta circa 5ms
? Perché il comportamento è sporadico?
Vedo che la dimensione del contenuto restituito è 225 bytes
(quando sa che i dati sono cahced), non riesco proprio a capire dove si trova il collo di bottiglia con il tempo di elaborazione della richiesta. Il mio computer host esegue windows con CPU Intel i7, 6 GB di RAM & unità SSD.