Built-in php web server caching issue

I am working on a test project using the embedded PHP web server and I am testing some ideas.

I want to implement my own caching mechanism for frequently used resources (png, jpg, json, txt, etc.) in order to reduce the load on the embedded server in php.

I start the embedded server as follows:

php -S 127.0.0.1:80 -t public router.php

So, the document root on the embedded server is set to public , and it launches router.php (since I also assume to implement a simple rewrite function).

Here is the contents of my router.php file:

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

I tested resource caching (png image) by visiting the following URL: http: //localhost/apple-icon-120x120.png

So, this is the first resource of the resource, so the service returns a resource with an HTTP 200 response, as expected, takes about 307ms : enter image description here

Now, if I press the F5 button to reload the page, the server will return HTTP 304 (not changed), as expected, and the request took about 5ms (excellent !!): enter image description here

If I press F5 third time, the server still returns HTTP 304 (not changed), as expected, however this time the request received approximately 306ms again (as if the resource were not cached): enter image description here

If I keep pressing F5 , the request processing time randomly alternates between 5m and approx 307ms .

Any ideas why this is so? As soon as the resource is cached, should it constantly return 304 and process the request approx 5ms ? Why is sporadic behavior?

I see that the size of the returned content is 225 bytes (when it knows the data is cached), I just can’t figure out where the bottleneck is with the request processing time. My host computer works with windows with an Intel i7 processor, 6 GB of RAM and SSDs.

+5
source share
1 answer

Your router file is working fine. I tested it locally and it behaves as expected: the first time is HTTP 200 with download, and then HTTP 304 with only headers.

Looking at your timeline, a response of 11.9 KB requires 307 ms, which is clearly too slow.

You get HTTP 304, so your script should be output without sending the file. However, to send the status code 304 in the first PHP instance, you still need to find mtime and calculate the hash of the md5 file. File access is probably the bottleneck.

Response times ranging from 5 ms to 300 ms can be caused by disk caching. Maybe you have a hard drive or a hybrid drive?

Why not repeat microtime() at the beginning, before mtime and after computing the hash?

0
source

Source: https://habr.com/ru/post/1233784/


All Articles