奇淫技巧 / 运维笔记

WordPress 启用memcached动静缓存

Einic Yeo · 3月18日 · 2019年 · · · ·

Memcached是一款开源、高性能、分布式内存对象缓存系统,可应用各种需要缓存的场景,其主要目的是通过降低对Database的访问来加速web应用程序。它是一个基于内存的“键值对”存储,用于存储数据库调用、API调用或页面引用结果的直接数据,如字符串、对象等。

PHP有2个组件memcache和memcached,基本都是教你怎么安装memcached,但不去解释两者之间的区别。

简单解释:

基于的库不同

memcache扩展是原生的(基于pecl扩展库)

memcached扩展是基于libmemcached库开发的,出现较晚,功能更加完善。

这里推荐使用memcached。

一、部署memcached

yum  install  memcached -y

#启动memcached

service  memcached start

#添加开机启动

chkconfig memcached on

集成php-memcached扩展

先安装libmemcached   这里参考了张戈的博客..

编译libmemcached 之前需要安装cyrus-sasl-devel

yum install cyrus-sasl-devel

开始编译libmemcached

wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz
tar zxvf libmemcached-1.0.18.tar.gz
cd libmemcached-1.0.18
./configure --with-memcached=/usr/local/memcached --prefix=/usr/local/libmemcached
make && make install
cd ..

安装php-memcached组件

#从官方下载php-memcached的最新源码包 
wget http://pecl.php.net/get/memcached-3.1.3.tgz
#解压和编译 tar zxvf memcached-3.1.3.tgz && cd memcached-3.1.3
#注意已有php的实际路径
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config --with-libmemcached-dir=/usr/local/libmemcached
make && make install

编辑php.ini文件,在最后插入如下参数

extension=memcached.so

查看是否加载成功

php -m | grep memcached

测试缓存

<?php
$m = new Memcached();
$m->addServer( '127.0.0.1', 11211 );
$m->set( 'foo', 100 );
echo $m->get( 'foo' ) . "\n";

保存代码为test.php,执行php -f test.php 输出100表示安装成功

二、Wordpress 启用动态缓存

1.安装插件

https://github.com/tollmanz/wordpress-pecl-memcached-object-cache

下载并解压得到的 object-cache.php,上传到 wp-content 目录即可开启memcached缓存。

2.查看效果

做完第2步之后,去网站前台刷新几次,产生缓存,然后从官方下载探针:

http://pecl.php.net/get/memcache-3.0.8.tgz

解压,得到memcache.php文件,编辑找到下面代码:

define('ADMIN_USERNAME','memcache');    // Admin Username
define('ADMIN_PASSWORD','password');    // Admin Password
define('DATE_FORMAT','Y/m/d H:i:s');
define('GRAPH_SIZE',200);
define('MAX_ITEM_DUMP',50);
 
$MEMCACHE_SERVERS[] = 'mymemcache-server1:11211'; // add more as an array
$MEMCACHE_SERVERS[] = 'mymemcache-server2:11211'; // add more as an array

修改为:

define('ADMIN_USERNAME','memcache');    // Admin Username
define('ADMIN_PASSWORD','password');    // Admin Password
define('DATE_FORMAT','Y/m/d H:i:s');
define('GRAPH_SIZE',200);
define('MAX_ITEM_DUMP',50);
 
$MEMCACHE_SERVERS[] = '127.0.0.1:11211'; // add more as an array

将memcache.php上传到网站目录,访问memcache.php这个文件,即可看到memcached状态:

登录后会发现里面没有Hits数据,这说明Wordpress没有成功连接到memcached

在wp-config.php加入以下参数:

global $memcached_servers;
$memcached_servers = array(
    array(
        '127.0.0.1', // Memcached server IP address
         11211        // Memcached server port
    )
);

刷新页面,已可以获取到Hits数据


三、Wordpress 启用静态缓存

到前面这一步已经完成了数据库查询的动态缓存,如果想要进一步提高性能,还可以类似与wp supercache或fastcgi缓存一下将网站的页面静态化,只不过存储在memcached分配的内存中,而不是硬盘上的文件。

这里要用到的插件叫做batcache,代码的readme文件里解释了这个名称的由来。bat并不表示真的和蝙蝠有什么联系,而是正好发布前夕wp-supercache已经发布,为了不和其他缓存插件冲突而用了这个名字。

首先下载官方插件项目的代码包batcache,解压缩后得到了advanced-cache.php文件,将其放入wordpress网站目录的wp-content/下。

然后在wordpress站点根目录下,在wp-config.php文件内加入一行

define('WP_CACHE', true);

batcache相关的配置在advanced-cache.php中的batcache类中,查找下面这几行

var $max_age =  3600; // Expire batcache items aged this many seconds (zero to disable batcache)
var $remote  =    0; // Zero disables sending buffers to remote datacenters (req/sec is never sent)
var $times   =    2; // Only batcache a page after it is accessed this many times... (two or more)
var $seconds =  120; // ...in this many seconds (zero to ignore this and use batcache immediately)

在此将缓存有效期设为3600秒,也就是过1小时后缓存将重新生成。在120秒内,连续访问该页面2次将生成缓存。具体数字可以根据实际情况修改。

测试一下,将网站的某个页面刷新几次,在Chrome的开发者工具源码页,注意查看body元素的footer里面,包含了下面一段,表明当前页面是由memached缓存生成的。

<!--
    generated in 0.349 seconds
    28088 bytes batcached for 300 seconds
-->

注:针对博客类型的小站,最好还是使用fastcgi的方案实现全静态化。如果动态类型较多,可以采用memcached缓存方案,但是并发处理能力没有fastcgi的好。

四、WordPress 启用WorkBox

若你是一个追求极致Web体验的站长,那你一定或多或少都听说过Service Worker,而现在已经是2019年了,Service Worker已经不是一项令人惊叹的技术了,Service Worker会接管全站的请求,若一不留神用户说不定就再也无法看到站点最新的资讯了,不过Google Chrome 团队推出了 Workbox,使编写缓存规则不再困难。

注册Service Worker 在主题的functions.php加入以下代码 :

function origami_setting_workbox()
{
    echo "<script>if ('serviceWorker' in navigator) {
        window.addEventListener('load', () => {
            navigator.serviceWorker.register('/sw.js');
        });
    }</script>";
}
add_action('wp_footer', 'origami_setting_workbox', '101');

在根目录下创建sw.js,并且写入下面内容(以下均为参考,具体配置请根据情况进行配置)

importScripts('https://cdn.jsdelivr.net/npm/[email protected]/workbox/workbox-sw.js');
workbox.setConfig({
    modulePathPrefix:'https://cdn.jsdelivr.net/npm/[email protected]/workbox/'
});

if (workbox) {
  console.log(`Yay! Workbox is loaded`);
} else {
  console.log(`Boo! Workbox did not load `);
}

// 定义缓存版本号和默认 Cache Storage 条目数
let cacheSuffixVersion = '-181111';
const maxEntries = 100;

workbox.routing.registerRoute(
    // 使用正则表达式匹配路由
    /.*\.html'/,
    workbox.strategies.cacheFirst({
        // cache storage 名称和版本号
        cacheName: 'html-cache' + cacheSuffixVersion,
        plugins: [
            // 使用 expiration 插件实现缓存条目数目和时间控制
            new workbox.expiration.Plugin({
                // 最大保存项目
                maxEntries,
                // 缓存 30 天
                maxAgeSeconds: 30 * 24 * 60 * 60,
            }),
            // 使用 cacheableResponse 插件缓存状态码为 0 的请求
            new workbox.cacheableResponse.Plugin({
                statuses: [0, 200],
            }),
        ]
    })
);

workbox.routing.registerRoute(
    new RegExp('https://www\.infvie\.com.*'),
    workbox.strategies.networkFirst({
        options: [{
            // 超过 3s 请求没有响应则 fallback 到 cache
            networkTimeoutSeconds: 3,
        }]
    })
);

workbox.routing.registerRoute(
    // Cache Image File
    /.*\.(?:png|jpg|jpeg|svg|gif)/,
    workbox.strategies.staleWhileRevalidate({
        cacheName: 'img-cache' + cacheSuffixVersion,
        plugins: [
            // 使用 expiration 插件实现缓存条目数目和时间控制
            new workbox.expiration.Plugin({
                // 最大保存项目
                maxEntries,
                // 缓存 30 天
                maxAgeSeconds: 30 * 24 * 60 * 60,
            }),
            // 使用 cacheableResponse 插件缓存状态码为 0 的请求
            new workbox.cacheableResponse.Plugin({
                statuses: [0, 200],
            }),
        ]
    })
);

workbox.routing.registerRoute(
    // Cache CSS & JS files
    /.*\.(css|js)/,
    workbox.strategies.staleWhileRevalidate({
        cacheName: 'static-assets-cache',
        plugins: [
            // 使用 expiration 插件实现缓存条目数目和时间控制
            new workbox.expiration.Plugin({
                // 最大保存项目
                maxEntries,
                // 缓存 30 天
                maxAgeSeconds: 30 * 24 * 60 * 60,
            }),
            // 使用 cacheableResponse 插件缓存状态码为 0 的请求
            new workbox.cacheableResponse.Plugin({
                statuses: [0, 200],
            }),
        ]
    })
);

workbox.routing.registerRoute(
    // Cache Fonts files
    /.*\.(woff|woff2)/,
    workbox.strategies.staleWhileRevalidate({
        cacheName: 'static-assets-cache',
        plugins: [
            // 使用 expiration 插件实现缓存条目数目和时间控制
            new workbox.expiration.Plugin({
                // 最大保存项目
                maxEntries,
                // 缓存 30 天
                maxAgeSeconds: 30 * 24 * 60 * 60,
            }),
            // 使用 cacheableResponse 插件缓存状态码为 0 的请求
            new workbox.cacheableResponse.Plugin({
                statuses: [0, 200],
            }),
        ]
    })
);

workbox.routing.registerRoute(
    /.*\?action.*/,
    workbox.strategies.networkFirst()
);

workbox.routing.registerRoute(
    /.*&action.*/,
    workbox.strategies.networkOnly()
);

workbox.routing.registerRoute(
    /.*wp-admin.*/,
    workbox.strategies.networkOnly()
);

workbox.routing.registerRoute(
    /.*wp-login.*/,
    workbox.strategies.networkOnly()
);

workbox.routing.registerRoute(
    /.*sitemap.*/,
    workbox.strategies.networkOnly()
);

workbox.routing.registerRoute(
    /.*feed.*/,
    workbox.strategies.networkOnly()
);

workbox.routing.registerRoute(
    /.*\.php/,
    workbox.strategies.networkOnly()
);

workbox.routing.registerRoute(
    /.*syfxlin.*/,
    workbox.strategies.networkOnly()
);

workbox.skipWaiting();
workbox.clientsClaim();

若成功引入就会在浏览器的控制台中输出Yay! Workbox is loaded ? 同时可以在开发工具中的Application选项卡中的Service Workers中看到激活信息。

参考文献

https://memcached.org/

http://www.runoob.com/memcached/memcached-install.html

http://xslwahaha.blog.51cto.com/4738972/1627129 

0 条回应