缓存动态生成的页面

时间:2018-06-18 08:24:46

标签: sql-server cloudflare response-time

我们希望加快我们的网站速度。更具体地说,我们希望降低TTFB。我们的网站主要包括基于url路径(提取主题)和url路径中的参数动态生成的页面。 这些条目被放入一个sql查询中,该查询从我们使用php执行的数据库中提取所有正确的数据。

问题在于:

这些查询可以很好地生成页面以及与它们相关的所有信息(例如标签)。 但是,每次访问者访问页面时重新运行代码都会花费大量时间,从而导致TTFB /服务器响应时间过长。实质上,这些页面只需要每月使用sql查询更新一次。在它之间,应该可以将它们作为预加载/预生成的静态HTML页面提供(直到我们指示刷新)。我们目前正在使用Cloudflare作为CDN,它已经非常好地加速了网站。现在,即使我们有“Cache Everything”的页面规则,我们仍然可以看到它重新运行包含sql查询的php代码。

问题:

有没有人知道实现缓存网站动态部分这一目标的好方法?无论是Cloudflare还是其他方式?我知道Akamai提供这项服务,但显然有一些转换成本与将网站交换到另一个CDN有关,我们对Cloudflare非常满意。

提前致谢!

2 个答案:

答案 0 :(得分:4)

如果您的网站每天都有数百个访问者,那么您可能希望为您的网站实施某种缓存机制,以加快页面加载时间。每个客户端 - 服务器请求包含多个数据库查询,服务器响应和处理时间,从而增加了整个页面加载时间。最常见的解决方案是制作称为缓存文件的动态页面的副本,并将它们存储在单独的目录中,以后可以将其作为静态页面提供,而不是一次又一次地重新生成动态页面。 了解动态网页&缓存文件

缓存文件是动态页面生成的静态副本,这些文件一次生成并存储在单独的文件夹中,直到它过期,当用户请求内容时,提供相同的静态文件而不是动态生成的页面,从而绕过需要使用服务器端代码一遍又一遍地重新生成HTML并从数据库请求结果。例如,运行多个数据库查询,计算和处理PHP代码到HTML输出需要几秒钟,增加整个页面加载时间与动态页面,但缓存文件只包含纯HTML代码,您可以在任何文本编辑器中打开它或浏览器,这意味着它根本不需要处理时间。

动态页面: - 下图中的示例显示了如何生成动态页面。顾名思义,它是完全动态的,它与数据库对话,并根据用户在请求期间提供的不同变量生成HTML输出。例如,用户可能希望列出特定作者的所有书籍,它可以通过向数据库发送查询并生成新的HTML内容来做到这一点,但每个请求都需要几秒钟来处理也使用某个服务器内存,这不是如果网站收到的访客很少,那就太大了。但是,考虑到数百名访问者一次又一次地从您的网站请求和生成动态页面,这将大大增加压力,导致客户端浏览器上的输出延迟和HTTP错误。

动态页面实例

缓存文件: - 下图说明了如何提供缓存文件而不是动态页面,如上所述,缓存文件只是静态网页。它们包含纯HTML代码,缓存页面内容改变的唯一方法是Web开发人员手动编辑文件。正如您所看到的,缓存文件既不需要数据库连接也不需要处理时间,它是一致的降低服务器压力和页面加载时间的理想解决方案。

缓存文件-示例 PHP缓存

还有其他方法可以使用PHP缓存动态页面,但每个人都使用的最常用的方法是PHP输出缓冲区和文件系统功能,结合这两种方法我们可以拥有宏伟的缓存系统。

PHP输出缓冲区: - 它有趣地提高了性能并减少了下载所需的时间,因为输出不是分段发送到浏览器而是整个HTML页面作为一个变量。该方法非常简单,请看下面的代码:

<?php
ob_start(); // start the output buffer

/* the content */
ob_get_contents();  gets the contents of the output buffer
ob_end_flush(); // Send the output and turn off output buffering
?>

当您在代码顶部调用ob_start()时,它会打开输出缓冲,这意味着此后的任何内容都将存储在缓冲区中,而不是在浏览器上输出。可以使用ob_get_contents()检索缓冲区中的内容。您应该在代码末尾调用ob_end_flush()将输出发送到浏览器并关闭缓冲。

PHP文件系统: - 您可能熟悉PHP文件系统,它是PHP核心的一部分,它允许我们读写文件系统。看看下面的代码。

$fp = fopen('/path/to/file.txt', 'w');  //open file for writing
fwrite($fp, 'I want to write this'); //write 
fclose($fp); //Close file pointer

正如您所看到的,代码的第一行fopen()打开了要写入的文件,模式'w'将文件指针放在文件的开头,如果文件不存在,它会尝试创建一个。第二行fwrite()将字符串写入打开的文件,最后fclose()关闭代码开头的成功打开的文件。 实现PHP缓存

现在你应该非常清楚PHP输出缓冲区和文件系统,我们可以使用这两种方法来创建我们的PHP缓存系统。请看下面的图片,流程图为我们提供了有关缓存系统的基本概念。

PHP-高速缓存系统

当用户请求内容时,循环开始,我们只检查当前请求的页面是否存在缓存副本,如果不存在,我们生成新页面,创建缓存副本然后输出结果。如果缓存已经存在,我们只需要获取文件并将其发送到用户浏览器。

看看下面的Full PHP缓存代码,你可以将它复制并粘贴到你的PHP项目中,它应该完美地工作,如上面的流程图所示。您可以使用代码中的设置,修改缓存过期时间,缓存文件扩展名,忽略页面等。

<?php
//settings
$cache_ext  = '.html'; //file extension
$cache_time     = 3600;  //Cache file expires afere these seconds (1 hour = 3600 sec)
$cache_folder   = 'cache/'; //folder to store Cache files
$ignore_pages   = array('', '');

$dynamic_url    = 'http://'.$_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . $_SERVER['QUERY_STRING']; // requested dynamic page (full url)
$cache_file     = $cache_folder.md5($dynamic_url).$cache_ext; // construct a cache file
$ignore = (in_array($dynamic_url,$ignore_pages))?true:false; //check if url is in ignore list

if (!$ignore && file_exists($cache_file) && time() - $cache_time < filemtime($cache_file)) { //check Cache exist and it's not expired.
ob_start('ob_gzhandler'); //Turn on output buffering, "ob_gzhandler" for the compressed page with gzip.
readfile($cache_file); //read Cache file
echo '<!-- cached page - '.date('l jS \of F Y h:i:s A', filemtime($cache_file)).', Page : '.$dynamic_url.' -->';
ob_end_flush(); //Flush and turn off output buffering
exit(); //no need to proceed further, exit the flow.
}
//Turn on output buffering with gzip compression.
ob_start('ob_gzhandler');
######## Your Website Content Starts Below #########
?>
<!DOCTYPE html>
<html>
<head>
<title>Page to Cache</title>
</head>
<body>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer ut tellus libero.
</body>
</html>
<?php
######## Your Website Content Ends here #########

if (!is_dir($cache_folder)) { //create a new folder if we need to
mkdir($cache_folder);
}
if(!$ignore){
$fp = fopen($cache_file, 'w');  //open file for writing
fwrite($fp, ob_get_contents()); //write contents of the output buffer in Cache file
fclose($fp); //Close file pointer
}
ob_end_flush(); //Flush and turn off output buffering

?>

您必须将PHP内容放在所附的注释行之间。事实上,我建议将它们放在单独的页眉和页脚文件中,以便它可以为所有不同的动态页面生成和提供缓存文件。如果你仔细阅读代码中的注释行,你会发现它非常自我解释。

答案 1 :(得分:0)

您可以在cloudflare的边缘进行此操作,以获得更好的性能。令人高兴的是,您可以随时将域设置为“开发中”以查看代码更改-无需更改服务器端机制。

您的页面规则如下所示。注意通配符的url变量。这意味着任何具有该变量名称的url都将被缓存在边缘。您应该可以轻松地在50毫秒内看到TTFB +整个html下载。

还要注意到期时间。您说了一个月,所以我选择了该设置。但我可能将其设置为“ 1天”。只是为了让我随时注意。

enter image description here