BAE 3.0 上的 WordPress(五):巧用 BCS 缓存,让速度飞

BAE 3.0 上的 WordPress(四):新的缓存设想 中,我提到了使用 BCS 缓存,目前我就已经实现了!

但是,问题还是有的,就是:有时候,文章发布、评论发表要自己手动更新缓存,无法自动更新。

很简单,在根目录创建一个 index-with-bcs.php,写入:

<?php

// 模式设置
$debug = 1; //开关 DeBug 模式(0:Off;1:On)
$display_cached_by_bcs = 1;  //显示 Cache By BCS(0:Off;1:On)

$start = microtime(); // 计算页面加载时间

// BAE 获取真实 IP
$RealIP = str_replace(", ", "", str_replace(getenv('REMOTE_ADDR'), "", getenv('HTTP_X_FORWARDED_FOR')));
if (false === getenv('HTTP_X_FORWARDED_FOR')) {
	$_SERVER['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
} else {
	$_SERVER['REMOTE_ADDR'] = $RealIP;
}

define('WP_USE_THEMES', true); // 不这样,主题就没了。

require_once ('bcs.class.php'); // 载入 BCS SDK
$cache_bucket = 'bucket'; // 缓存所用的 Bucket,建议使用“私有”模式和单独 Bucket,不要混用
$cache_ak = 'AK'; // API Key,BAE 3.0 环境需要手动填写,2.0 可用 getenv('HTTP_BAE_ENV_AK')
$cache_sk = 'SK'; // Scret Key,BAE 3.0 环境需要手动填写,2.0 可用 getenv('HTTP_BAE_ENV_SK')
$baidu_bcs = new BaiduBCS($cache_ak, $cache_sk);

$refresh_key = 'r'; // 单页缓存刷新 Key,默认 r,刷新方式就是访问你要刷新的页面 + ?r=y,强烈建议更改此选项
$clean_key = 'c'; // 缓存清空 Key,默认 c,刷新方式就是访问站点任意页面 + ?c=y,强烈建议更改此选项

$url = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$url = str_replace('?' . $refresh_key . '=y', '', $url);
$url = str_replace('?' . $clean_key . '=y', '', $url);
$key = md5($url);
$object = '/' . md5($url);

// 检查 WordPress 是否处于登录状态下
$cookie = var_export($_COOKIE, true);
$loggedin = preg_match("/wordpress_logged_in/", $cookie);

// 如果已经缓存,且为游客访问(非登陆状态下),就直接加载缓存内容
if ($baidu_bcs->is_object_exist($cache_bucket, $object) && !$loggedin && !strpos($url, '/feed/') && !isset($_GET[$refresh_key]) && !isset($_GET[$clean_key])) {

	echo $baidu_bcs->get_object($cache_bucket, $object)->body;
	$cached = 1;
	$msg = '<!-- Page cached -->';
// 如果检测到刷新指令,就清空该页缓存
} elseif ($_GET[$refresh_key] == 'y') {

	require('./wp-blog-header.php');
	$baidu_bcs->delete_object($cache_bucket, $object);
	$msg = '<!-- Page cache deleted -->';

// 如果检测到清空指令,就清空所有缓存
} elseif ($_GET[$clean_key] == 'y') {

	require('./wp-blog-header.php');
	$list_opt = array('start' => 0);
	$list_cache = json_decode($baidu_bcs->list_object($cache_bucket, $list_opt)->body, true);
	$i = 0;
	while($i < 1000){
		$object= $list_cache["object_list"][$i]["object"];
		$baidu_bcs->delete_object($cache_bucket, $object);
		$i++;
	}
	$msg = '<!-- Cache flushed -->';
// 如果登录的情况下,就不缓存
} elseif ($loggedin) {

	require('./wp-blog-header.php');
	$msg = '<!-- Page not cached -->';
// 否则,缓存该页面
} else {

	ob_start();

	require('./wp-blog-header.php');

	$html = ob_get_contents();

	ob_end_clean();
	echo $html;

	// 如果是 404 页面 或 搜索结果 页面就不缓存
	if (!is_404() && !is_search()) {
		// 缓存 7 天,但不知过期是否会自动处理
		$cache_opt = array('header' => array(
			'Expires' => 'modify plus 7 days',
			'Content-Type' => 'text/plain'
			)
		);
		$baidu_bcs->create_object_by_content($cache_bucket, $object, $html, $cache_opt);
		$msg = '<!-- Page is cached -->';
	}
}

$end = microtime(); // 得到加载完成时间

if ($cached && $display_cached_by_bcs) {
	echo "\n" . '<!-- Dynamic page generated in ' . t_exec($start, $end) . ' seconds -->' . "\n";
	echo '<!-- Cached page generated by Nikbobo BCS Cache -->' . "\n";
	echo '<!-- BCS Cache: ' . $key . ' -->' . "\n";
}

// 如果 DeBug 模式开启,就显示 DeBug 信息
if ($debug) {
    echo "\n" . $msg . "\n";
}

// 时间比对
function t_exec($start, $end) {
	$t = (getmicrotime($end) - getmicrotime($start));
	return round($t,5);
}

// 获取页面加载时间
function getmicrotime($t) {
	list($usec, $sec) = explode(" ",$t);
	return ((float)$usec + (float)$sec);
}

?>

就可以了。

但是,记住 BAE 3.0 服务的 SDK 需要开发者自己安装到环境中,所以自己下载 BCS SDK 扔到根目录。

我们还要做的是修改 App.Conf 将伪静态修改到 index-with-bcs.php,具体步骤是:

编辑 App.Conf,将:

 - url : /
    script : index.php
  - url : (.*)
    script : /index.php

替换为:

 - url : /
    script : index-with-bcs.php
  - url : (.*)
    script : /index-with-bcs.php

然后,为了尽可能避免发布文章不自动更新、发表评论不自动更新,我们需要在主题的 Functions.php 中添加如下代码:

/*
 * BCS 缓存清空 (当发布文章、评论时)
 */
function bcs_cache_refresh() {
	global $batcache;

	$post = get_post($post_id);
	if ( $post->post_type == 'revision' || get_post_status($post_id) != 'publish' )
		return;

	bcs_cache_refresh_url( get_option('home') );
	bcs_cache_refresh_url( trailingslashit( get_option('home') ) );
	bcs_cache_refresh_url( get_permalink($post_id) );
}
add_action( 'wp_trash_post', 'bcs_cache_refresh', 0 );
add_action( 'publish_post', 'bcs_cache_refresh', 0 );
add_action( 'edit_post', 'bcs_cache_refresh', 0 ); // leaving a comment called edit_post
add_action( 'delete_post', 'bcs_cache_refresh', 0 );
add_action( 'publish_phone', 'bcs_cache_refresh', 0 );
add_action( 'clean_post_cache', 'bcs_cache_refresh' );

function bcs_cache_refresh_url($url) {
	if ( empty( $url ) )
		return false;
	require_once ('bcs.class.php');
	$cache_bucket = 'Bucket'; // 缓存所用的 Bucket,建议使用“私有”模式和单独 Bucket,不要混用
	$cache_ak = 'AK'; // API Key,BAE 3.0 环境需要手动填写,2.0 可用 getenv('HTTP_BAE_ENV_AK')
	$cache_sk = 'SK'; // Scret Key,BAE 3.0 环境需要手动填写,2.0 可用 getenv('HTTP_BAE_ENV_SK')
	$baidu_bcs = new BaiduBCS($cache_ak, $cache_sk);
	$cache_object = '/' . md5( $url );
	$baidu_bcs->delete_object($cache_bucket, $cache_object);
	return true;
}

话说,SiteMap.XML 改一改,也可以缓存一下。敬请期待。

有人问这个有什么用,不是有 Cache 么?但是我想说,等到 Cache 收费时,用处就来了。

此文章是由nikbobo发表在旧博客分类目录的。将固定链接加入收藏夹。

关于 nikbobo

Nikbobo,本名刘永强,记忆空间站长,男,1998 年出生于广东茂名,至今(2022 年)23 岁,目前(2022 年)就读于广州大学华软软件学院,常以“nikbobo”这个网名混迹互联网。如无特殊注明,Nikbobo 在本站发表的文章,遵循 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议。详情请参阅关于页面的作者介绍。

BAE 3.0 上的 WordPress(五):巧用 BCS 缓存,让速度飞》上有9个想法

    • 对的,貌似原因来自于 WordPress 的 URL 与 index-with-bcs.php 的不一致,多了“/”,但是有些又没问题。
      建议博主参考下 WP Super Cache 这类缓存插件。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注