如何让WordPress的所有请求只需要通过Nginx处理,不经过PHP和Mysql,从而加快站点访问速度?

24,481次阅读
没有评论

共计 2218 个字符,预计需要花费 6 分钟才能阅读完成。

wp 请求响应过程

wordpress 响应请求大致分为如下几个过程:

Nginx 接收请求 -> php-fpm 进程运行指定 php 脚本 -> php 在 mysql 内查询相应数据 -> 处理返回给 Nginx  -> Nginx 响应用户请求

因为不存在缓存的过程,所以每次处理请求都要重新查询数据库,所以 wp 有很多流行的静态缓存方案;

wp 缓存方式

1. 文件缓存

初次请求 -> Nginx 接收请求 -> php-fpm 进程运行指定 php 脚本 -> php 在 mysql 内查询相应数据 -> 缓存本次请求产生的页面数据到文件 A  -> 处理返回给 Nginx  -> Nginx 响应用户请求

缓存之后的请求过程如下:

缓存之后的所有请求  -> Nginx 接收请求  -> php-fpm 进程运行指定 php 脚本 -> 判断是否存在缓存文件  -> 输出缓存文件的内容给 Nginx ->  Nginx 响应本次请求

相较于没有缓存的情况,大大的减少了 Mysql 的查询次数,所有文件缓存是比较流行的一种方式,但是这种方式在数据量很大的时候,能起到的作用还是比较有限的。

2. 内存持久化缓存

初次请求 -> Nginx 接收请求 -> php-fpm 进程运行指定 php 脚本 -> php 在 mysql 内查询相应数据 -> 缓存本次请求产生的页面数据到 Redis  -> 处理返回给 Nginx  -> Nginx 响应用户请求

内存持久化缓存最常见的是将页面缓存到 Redis,缓存之后的每次请求直接从 Redis 获取数据;因为每次查询都是操作内存,所以速度非常快,响应过程大致如下:

缓存之后的所有请求  -> Nginx 接收请求  -> php-fpm 进程运行指定 php 脚本 -> 判断 Redis 是否存在缓存  -> 输出缓存文件的内容给 Nginx ->  Nginx 响应本次请求

缺点就是数据量大的时候,占用的内存比较多,所以这种方式相较于文件缓存,使用的比较少。

Nginx+ 文件缓存

Nginx 响应静态文件请求出了名的快,所以我们可以将响应请求的方式调整成如下过程:

缓存之后的所有请求 -> Nginx 接收请求  -> Nginx 判断当前请求是否有缓存文件 ->  直接响应本次请求的缓存文件

页面生成缓存之后,响应请求不再经过 PHP 和 Mysql 等以外的程序,直接通过 Nginx 完成所有事情。实现方式如下:

1. 针对初次请求生成缓存文件

本次只是简要的说明可行性方案,有示例代码,无插件;编辑根目录的 index.php,在 define(‘WP_USE_THEMES’, true); 后加入如下代码:

/* 如果访问的不是后台 */
if(strpos($_SERVER['REQUEST_URI'],"wp-admin") === false){ob_start( function ( $html) {
	    
	    /* 非文章页 */
	    if(!is_singular()){return $html;}
	    
	    
	    /* 判断是移动还是 PC */
	    if (strpos($_SERVER['HTTP_HOST'], 'm.') !== false) {$cache_dir = "/m_cache";}else{$cache_dir = "/cache";}

		/* 判断文章密码 */
		if(is_single()){$post = get_post();
			if (!empty( $post->post_password ) ) {return $html;}
		}

		/* 获取请求的路径 */
		$location = $_SERVER['REQUEST_URI']; // 路径

		/* 去除参数,获取纯路径 */
		$match = preg_replace('/(?.*)/', "", $location );
		$query = $_SERVER['QUERY_STRING']; // 查询的参数

		/*
		 * 纯目录和 html 文件
		 * */
		if (( strpos( $match, '.') === false ) || (strpos( $match, '.html') !== false ) ) {


			$dir  = __DIR__ . $cache_dir . $match . '_' . $query;
			$file = __DIR__ . $cache_dir . $match . '_' . $query . '/index.html';



			if (! file_exists( $file) && ! empty($html) ) {if ( ! file_exists( $dir) ) {mkdir( $dir, 0777, true);
        		}
        			
				file_put_contents($file, $html, LOCK_EX);
			}
		}


		return $html;

	});
}

2. 修改 Nginx 伪静态匹配规则

location / {
    # 对于 POST 请求不走缓存
    if ($request_method ~ ^(POST)$){rewrite / /index.php?$args last;}	
    try_files /cache/$uri /cache${uri}_${args}/index.html  $uri $uri/  /index.php?$args;
}

修改之后的匹配规则变为,首先判断请求的文件在不在,然后判断 cached 目录下面又没有这个文件,然后判断有没有这个目录(目录内有没有 index 文件),最后将请求重定向到 wordpress 入口文件 index.php。

如果缓存文件存在,将会在 cached 目录内匹配到请求的目录,然后直接响应用户请求。

3. 最后总结

还有很多细节需要完善,比如如何处理缓存更新,比如有些主题移动端、PC 端页面代码不一致时如何处理等等。

但是总得来说,通过这种方式加速后,访问速度能快一个量级。

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-09-10发表,共计2218字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)