本文我们来介绍WordPress缓存插件wp-super-cache在nginx下如何配置rewrite规则,后面补充了WP Super Cache的介绍,实现WordPress提交评论的时删除该页面的WP-Super-Cache缓存的方法.
WordPress的缓冲插件wp-super-cache默认支持apahce的缓冲方式,在生成了静态页面数据后,通过.htaccess的规则直接让apache读取静态文件,完全不经过PHP,可以很大的提高博客的页面性能.
但是Nginx的改写规则就没这么容易让代码来配置了,虽然wp-super-cache的第二种缓存方式就是为这种使用环境设计,但实际上是用了PHP来提供静态数据了,在使用apache benchmark压力的时候,php-cgi依然占很高的CPU占有率.
通过编写nginx的rewrite规则还是可以让nginx直接读取静态文件,参考来自Code Exchange: nginx rewrite rules for WordPress + WP Super Cache,这里的配置被很多地方引用过,但实际尝试使用过程看到那里面的代码还需要微调.
- server {
- listen 80;
- server_name apt-blog.net;
- root /var/www/pt-sites/wordpress;
- index index.html index.htm index.php;
- location / {
- # enable search for precompressed files ending in .gz
- # nginx needs to be complied using ?-with-http_gzip_static_module
- # for this to work, comment out if using nginx from aptitude
- gzip_static on;
- # if the requested file exists, return it immediately
- if (-f $request_filename) {
- break;
- }
- set $supercache_file '';
- set $supercache_uri $request_uri;
- if ($request_method = POST) {
- set $supercache_uri '';
- }
- # Using pretty permalinks, so bypass the cache for any query string
- if ($query_string) {
- set $supercache_uri '';
- }
- if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) {
- set $supercache_uri '';
- }
- # !!!! IMPORTANT
- # if we haven't bypassed the cache, specify our supercache file
- if ($supercache_uri ~ ^(.+)$) {
- set $supercache_file /wp-content/cache/supercache/$http_host/$1/index.html;
- }
- # only rewrite to the supercache file if it actually exists
- if (-f $document_root$supercache_file) {
- rewrite ^(.*)$ $supercache_file break;
- }
- # all other requests go to Wordpress
- if (!-e $request_filename) {
- rewrite ^(.*)$ /index.php?q=$1 last;
- } //Vevb.com
- }
- location ~ /.php$ {
- include fastcgi_params;
- fastcgi_pass 127.0.0.1:9000;
- fastcgi_index index.php;
- fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
- }
- }
需要重点关注的是set $supercache_uri这一行,这里的路径是wp-super-cache生成静态文件的路径,配置文件起作用的时候,这个路径会和$document_root组成最终静态文件的绝对路径,最终输出文件,所以如果这个路径不对的话,最终还是交给了index.php,缓冲就不起作用了.
wp-super-cache在wordpress目录/wp-content/cache/supercache/$http_host/下生成了各个请求url的目录,目录下是一个index.html静态文件,可以在wordpress工作时候,在这个目录下用命令watch find观察(在缓冲不多的情况下),总之小心的把这个路径写好,因为估计每个博客的permanent link的样式都不一样,wp-super-cache生成的目录也不一样,需要仔细调试一下.
当然这里的规则并没有安全包含了wp-super-cache 插件的功能,比如识别手机客户端之类的,如果需要还得仔细根据插件生成的.htaccess规则来添加到nginx。
完成后用apache benchmark压一下,Request per second应该很容易上百,而且php-cgi应该不会出现在top的列表前面了,CPU应该集中在nginx的子进程上,而且都是个位数CPU占有率,系统的load非常低。
Tips:发现测试结果不对时,可以尝试删除/wp-content/cache整个目录,让wp重新生成所有缓冲.
顺便说一下,如果仅使用ab测试压力,用不着安装整个apache2,只需要apt-get install apache2-utils.
WordPress缓存插件:WP Super Cache
WP Super Cache 的基本介绍:WP Super Cache 是 WordPress 官方开发人员 Donncha 开发,是当前最高效也是最灵活的 WordPress 静态缓存插件,它把整个网页直接生成 HTML 文件,这样 Apache 就不用解析 PHP 脚本,通过使用这个插件,能使得你的 WordPress 博客将显著的提速.
WP Super Cache 的缓存机制
WP Super Cache 缓存机制有两种,WP Cache 和 Super Cache。
WP Cache 缓存时,会在你的“wordpress 安装文件夹/wp-content/cache/”文件夹下生成一系列wp-cache-xxxxxx.html格式的文件,Super Cache 缓存时,则在你的“wordpress 安装文件夹/wp-content/cache/supercache/”文件夹下生成对应每一篇文章或者标签等的目录,名称为xxx.html,取决于你的文章ID是怎么设置,目录下面就是静态的 index.html 文件.
当你一个访问者来的你的站点,他没有登入或者也没有留言,这样他得到是一个在 WordPress cache 文件夹下的 supercache 子文件夹下的纯静态文件,其实你都可以自己到上面的 supercache 目录下去查看同样的永久链接的 HTML 文件的备份.
判断一个页面是否已经被缓存了,查看该页面的源代码,如果访问者已经登陆或者留了言,就会返回 WP Cache 函数生成的页面,并且最后一行会有“Cached page generated by WP-Super-Cache+缓存时间”这行字,就像下面这行代码一样:
<!-- Cached page generated by WP-Super-Cache on 2011-02-25 15:57:24 -->
而 Super Cache 缓存会多一行如下代码:
<!-- super cache -->
因为 Super Cache 是真正静态的,对搜索引擎和博客的速度非常有好处,而且有效的减轻了 php 和 Mysql 的查询压力,这点对于大型博客来说优势很明显,一般的较小的博客感觉就不怎么明显.
WP-Super-Cache 的使用设置
WP-Super-Cache 启用前的准备工作
①前提是固定链接不可用默认的,上传WP-Super-Cache插件,不要急着启用。
②赋予以下权限:
给wp-super-cache文件夹添加写权限。
给wp-content文件夹添加写权限。
在wp-content文件夹下新建cache文件夹并添加写权限。
③在网站根目录wp-config.php文件中
先检查是否有下面这段代码:
define('WP_CACHE',true);//Added by WP-Cache Manager
如果没有则在define(‘DB_NAME’的上一行(也就是添加在wp-config.php文件中语句的最前面) 添加如下代码:
define('WP_CACHE',true);//Added by WP-Cache Manager
然后启用插件,一般已经可以去设置了,如果还出错再接着下面步骤.
④看wp-content目录下面有没有有wp-cache-config.php这个文件,如果没有,直接把插件包里面的wp-cache-config-sample.php改名为wp-cache-config.php传到wp-content目录.
⑤再看wp-content目录里面有没有advanced-cache.php这个文件,如果没有,同样把插件包里面的wp-cache-phase1.php文件改名为advanced-cache.php同样传到wp-content目录.
⑥最后一步在wp-content目录下面建一个cache文件夹,再在cache文件夹下新建一个supercache文件夹.
⑦查看网站底部源代码,如果有类似下面的文字则说明没有开启成功,继续修改:
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
⑧查看网站底部源代码,有类似下面的文字则说明开启成功.
- <!-- Dynamic page generated in 2.703 seconds. -->
- <!-- Cached page generated by WP-Super-Cache on 2010-11-23 11:44:28 -->
- <!-- super cache -->
注:更改了网站文件后要进入“Tester&contents”选项点击“删除过期文件”“删除缓存”.
WP-Super-Cache 的设置
1.“Easy”:勾选“Caching On (Recommended)”,点击“更新状态”.
2.“高级选项”:(额外附加以下选项).
勾选“Compress pages so they’re served more quickly to visitors.”(开启gzip)
勾选“Don’t cache pages for known users.”不对认识的人使用缓存(比如登录者或发表评论者)
过期时限:0秒,0表示不启用,但当有新文章发表时、新评论时,仍可自动更新缓存.
“Preload”那里勾选“Preload mode”
3.“Preload”:勾选“Preload mode ”
注:其它所有选项默认即可。
WP-Super-Cache 完全删除的方法
①在后台禁用此插件。
②删除/wp-content/plugins/目录的wp-super-cache目录。
③删除wp-content目录下面的cache目录。
④删除wp-content目录下面的wp-config.php,advanced-cache.php两个文件。
⑤修改wp-config.php,把这一行删掉:define(‘WP_CACHE’,‘true’);
⑥如果主机本来是用.htaccess文件的要改回来(网站根目录与wp-content/cache都有)
实现WordPress提交评论的时删除该页面的WP-Super-Cache缓存的方法.
lnmp环境下的WordPress使用WP-Super-Cache插件,若要开启mod_rewrite 缓存模式,需要在nginx里面加入一些特定的规则,具体请见旧文:《nginx下wp super cache的mod_rewrite规则》。
用过WP-Super-Cache插件的应该都知道,在高级设置里面有一项【当某页面有新评论时,只刷新该页面的缓存】的功能,从字面上来说,就是当有人在某篇文章发起评论时,将删除该页面的缓存。
但是,经过我仔细测试发现,这个功能在我的博客并没有生效,个人猜测失败的原因可能是使用了ajax无刷新评论导致的。也就是采用ajax评论的方式,可能无法触发WP-Super-Cache的删除机制,从而导致这个功能的失效!总之,不管怎么样,反正在我的博客失效了,现在就要想办法解决这个问题。
既然你不行,那就我来,简单的加上几句并不高端的PHP代码后,就实现了这个功能,编辑主题下的comments-ajax.php文件,启用ajax评论的博客才有,找到如下代码:
- do_action('pre_comment_on_post', $comment_post_ID);
- do_action('pre_comment_on_post', $comment_post_ID);
然后,在这行代码之后添加删除缓存代码,保存即可.
- //有人评论将自动删除已存在缓存
- $post_data = get_post($post->ID, ARRAY_A);
- $slug = $post_data['post_name'];
- $cache_s = WP_CONTENT_DIR."/cache/supercache/".$_SERVER['SERVER_NAME']."/".$post->ID.".html/index.html";
- $cache_sd = WP_CONTENT_DIR."/cache/supercache/".$_SERVER['SERVER_NAME']."/".$post->ID.".html";
- $cache_p = WP_CONTENT_DIR."/cache/supercache/".$_SERVER['SERVER_NAME']."/".$slug."/index.html";
- $cache_pd = WP_CONTENT_DIR."/cache/supercache/".$_SERVER['SERVER_NAME']."/".$slug;
- if (file_exists($cache_s)) {
- unlink($cache_s);
- rmdir($cache_sd);
- }
- if (file_exists($cache_p)) {
- unlink($cache_p);
- rmdir($cache_pd);
- }
- //有人评论将自动删除已存在缓存
- $post_data = get_post($post->ID, ARRAY_A);
- $slug = $post_data['post_name'];
- $cache_s = WP_CONTENT_DIR."/cache/supercache/".$_SERVER['SERVER_NAME']."/".$post->ID.".html/index.html";
- $cache_sd = WP_CONTENT_DIR."/cache/supercache/".$_SERVER['SERVER_NAME']."/".$post->ID.".html";
- $cache_p = WP_CONTENT_DIR."/cache/supercache/".$_SERVER['SERVER_NAME']."/".$slug."/index.html";
- $cache_pd = WP_CONTENT_DIR."/cache/supercache/".$_SERVER['SERVER_NAME']."/".$slug;
- if (file_exists($cache_s)) {
- unlink($cache_s);
- rmdir($cache_sd);
- }
- if (file_exists($cache_p)) {
- unlink($cache_p);
- rmdir($cache_pd);
- }
现在有人提交评论时,将会判断是否存在该页缓存,如果存在就删除,从而实现了我要的功能,本来想用 is_page() 和 is_single()来判断页面内容,从而简化代码的,可惜不生效,至少用上面的笨方法了,反正能实现就可以了.
新闻热点
疑难解答
图片精选