解决WordPress Batcache插件无法工作的问题

本文同步自(最佳显示效果请点击):https://zohead.com/archives/fix-wordpress-batcache/

前几天看到 AlexYang 同学写的一篇非常好的关于在百度 BAE 云平台上启用 WordPress 博客缓存全页面加速的文章,由于 BAE 云平台不支持本地文件读写,WP Super Cache 之类的 WordPress 本地缓存插件无法正常工作(也不支持 NFS 目录作为缓存目录哦),文章中使用基于 BAE cache 空间的 memcache 接口,并通过 Batcache 这个 WordPress 插件实现全页面加速,据说缓存加速效果非常明显。

介绍缓存加速的文章请参考 [这里],Batcache WordPress 插件可以点击 [这里] 下载。

我按照上面文章中的介绍在 wp-content 目录中增加了 BAE 版本的 object-cache.php 文件和 Batcache 插件的 advanced-cache.php 文件,但在测试中发现始终没有看到作者所介绍的效果:首次访问站点之后缓存到内存,后续访问都会从缓存中读取,无需多余的数据库请求,网页 head 信息中始终没有 cache 的调试输出。

在参考 AlexYang 的文章做了多遍的检查之后,觉得一切条件都符合的,还无法正常缓存,只能看看 Batcache 的代码了。在 Batcache 代码中增加一堆调试信息,经过坑爹的调试过程(BAE 的应用日志查询功能简直是弱的让人无力吐槽的),终于发现真正原因:

Batcache 在判断页面请求时会检查当前请求所使用的 cookie,插件觉得某些情况下页面必须刷新,就忽略当前缓存的内容,例如:用户在文章下发表评论,这种情况下必须忽略之前的缓存,否则用户评论之后将无法看到自己评论的内容;还有一种情况就是管理员登录到后台了,这种情况下也必须禁用缓存,否则管理员对博客做的修改操作也将无法正常看到。

正是考虑到类似上面的情况,Batcache 在检测到一些 cookie 值时会禁用缓存,advanced-cache.php 中的判断代码如下:

// Never batcache when cookies indicate a cache-exempt visitor.
if ( is_array( $_COOKIE) && ! empty( $_COOKIE ) )
	foreach ( array_keys( $_COOKIE ) as $batcache->cookie )
		if ( $batcache->cookie != 'wordpress_test_cookie' && 
			( substr( $batcache->cookie, 0, 2 ) == 'wp' || substr( $batcache->cookie, 0, 9 ) == 'wordpress' || substr( $batcache->cookie, 0, 14 ) == 'comment_author' ) )
			return;

这就表示 Batcache 发现如果请求中的 cookie 是以 wp、wordpress 或者 comment_author 开头时就禁用缓存,这样后台管理、用户评论等功能才能正常工作。

而通过对我访问博客时的数据进行抓包显示,由于我安装了 WordPress Mobile Pack 这个插件,访问博客时会向浏览器发送切换浏览类型的 wpmp_switcher cookie,这就刚好在 Batcache 插件的过滤范围内,当然就导致 Batcache 全页面缓存始终无法起作用。知道原因了就好办,将 wp-content 目录下的 advanced-cache.php 的判断 cookie 处改为:

// Never batcache when cookies indicate a cache-exempt visitor.
if ( is_array( $_COOKIE) && ! empty( $_COOKIE ) )
	foreach ( array_keys( $_COOKIE ) as $batcache->cookie )
		if ( $batcache->cookie != 'wordpress_test_cookie' && $batcache->cookie != 'wpmp_switcher' && substr( $batcache->cookie, 0, 12 ) != 'wp-settings-' && 
			( substr( $batcache->cookie, 0, 2 ) == 'wp' || substr( $batcache->cookie, 0, 9 ) == 'wordpress' || substr( $batcache->cookie, 0, 14 ) == 'comment_author' ) )
			return;

刷新页面就可以看到缓存起作用了,不得不说启用内存缓存之后,页面访问速度还是有不少提升了。

备注:上面的修改代码中另外还增加了 wp-settings- 开头的 cookie 项,因为测试时发现有时还会有这个 cookie 导致缓存不起作用。

网上有不少的网友说装了 Batcache 插件之后缓存没用,可以参考这个思路看看到底是什么 cookie 之类的条件不满足导致的。本文章为个人修改经验,如果有任何问题欢迎提出指正,玩的开心 ^_^