Val*_*out 1 sql-server response-time cloudflare
我们正在寻求加速我们的网站。更具体地说,我们希望降低 TTFB。我们的网站主要由根据 url 路径(提取主题)和 url 路径中的参数动态生成的页面组成。这些条目被放入一个 sql 查询中,该查询从我们使用 php 执行的数据库中提取所有正确的数据。
这是问题:
这些查询可以完美地生成页面以及与它们相关的所有信息(例如标签)。但是,每次访问者访问页面时都重新运行代码会花费大量时间,从而导致 TTFB/服务器响应时间过长。本质上,这些页面只需要每月使用 sql 查询更新一次。在这两者之间,应该可以将它们作为预加载/预生成的静态 HTML 页面提供(直到我们指示刷新)。我们目前正在使用 Cloudflare 作为 CDN,它已经在加速网站方面发挥了巨大的作用。现在,即使我们打开了“缓存所有内容”的页面规则,我们仍然可以看到它重新运行了包括 sql 查询在内的 php 代码。
问题:
有人知道实现缓存网站动态部分这一目标的好方法吗?是通过 Cloudflare 还是通过其他方式?我知道 Akamai 提供这项服务,但显然,将网站切换到另一个 CDN 会产生一些转换成本,我们对 Cloudflare 相当满意。
提前致谢!
小智 6
如果您的网站每天有数百个页面和许多访问者,您可能希望为您的网站实施某种缓存机制以加快页面加载时间。每个客户端-服务器请求都包含多个数据库查询、服务器响应和处理时间,从而增加了整体页面加载时间。最常见的解决方案是制作称为缓存文件的动态页面的副本,并将它们存储在单独的目录中,以后可以将其用作静态页面,而不是一次又一次地重新生成动态页面。了解动态页面和缓存文件
缓存文件是动态页面生成的静态副本,这些文件生成一次并保存在单独的文件夹中直到过期,当用户请求内容时,提供相同的静态文件而不是动态生成的页面,从而绕过重新生成的需要HTML 并使用服务器端代码一遍又一遍地从数据库中请求结果。例如,运行多个数据库查询,计算和处理 PHP 代码到 HTML 输出需要几秒钟,使用动态页面增加整体页面加载时间,但缓存文件仅由纯 HTML 代码组成,您可以在任何文本编辑器或浏览器,这意味着它根本不需要处理时间。
动态页面:— 下图中的示例显示了如何生成动态页面。顾名思义,它是完全动态的,它与数据库对话并根据用户在请求期间提供的不同变量生成 HTML 输出。例如,用户可能想要列出特定作者的所有书籍,它可以通过向数据库发送查询并生成新的 HTML 内容来实现,但是每个请求都需要几秒钟的时间来处理,并且会使用特定的服务器内存,这不是如果网站的访问者很少,这将是一个大问题。但是,考虑到数百名访问者一遍又一遍地从您的网站请求和生成动态页面,这会大大增加压力,从而导致客户端浏览器出现延迟输出和 HTTP 错误。
动态页面示例
缓存文件:— 下图说明了如何提供缓存文件而不是动态页面,如上所述,缓存文件只不过是静态网页。它们包含纯 HTML 代码,缓存页面内容更改的唯一方式是 Web 开发人员手动编辑文件。正如您所看到的,缓存文件既不需要数据库连接,也不需要处理时间,它是一致降低服务器压力和页面加载时间的理想解决方案。
缓存文件示例 PHP 缓存
PHP缓存动态页面还有其他的方式,但是大家最常用的就是PHP Output Buffer和Filesystem Functions,结合这两种方式我们就可以拥有华丽的缓存系统。
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
?>
Run Code Online (Sandbox Code Playgroud)
当您在代码顶部调用 ob_start() 时,它会打开输出缓冲,这意味着此后的任何内容都将存储在缓冲区中,而不是在浏览器上输出。可以使用 ob_get_contents() 检索缓冲区中的内容。您应该在代码末尾调用 ob_end_flush() 以将输出发送到浏览器并关闭缓冲。
PHP Filesystem :— 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
Run Code Online (Sandbox Code Playgroud)
如您所见,代码 fopen() 的第一行打开文件进行写入,模式 'w' 将文件指针放在文件的开头,如果文件不存在,它会尝试创建一个。第二行 fwrite() 将字符串写入打开的文件,最后 fclose() 关闭代码开头成功打开的文件。实现 PHP 缓存
现在您应该非常清楚 PHP 输出缓冲区和文件系统,我们可以使用这两种方法来创建我们的 PHP 缓存系统。请看下图,流程图为我们提供了缓存系统的基本概念。
php缓存系统
当用户请求内容时循环开始,我们只检查当前请求页面的缓存副本是否存在,如果不存在我们生成一个新页面,创建缓存副本然后输出结果。如果缓存已经存在,我们只需要获取文件并将其发送到用户浏览器。
看看下面的完整 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
?>
Run Code Online (Sandbox Code Playgroud)
您必须将 PHP 内容放在封闭的注释行之间,实际上我建议将它们放在单独的页眉和页脚文件中,以便它可以为所有不同的动态页面生成和提供缓存文件。如果您仔细阅读代码中的注释行,您应该会发现它几乎不言自明。