垃圾站 WP教程 WordPress为anylink插件增加缓存实现方法

WordPress为anylink插件增加缓存实现方法

最近在梳理网站的代码,想办法为网站加速,主要从代码、软件、网络层面进行优化,这一切都是从网站切换到HTTPS开始的。

已经连续观察了多日的CDN了,目前也就到了查缺补漏的阶段了。还将整个网站目前备份到了另一台服务器,将网站在本地解析到这台服务器上,开始了对代码的检查。开启了debug,把大的一些问题都处理了,然后也把主题的代码理了一遍,并且网站也加上了Redis缓存。但是发现,即使加上了Redis,有时候网页打开生成时间还是得一秒多,就很纳闷,一直想搞明白到底是什么情况。

排查工具

很早以前,就在主题的footer.php末尾,添加了下面的代码,以便于登录之后可以看到当前网页的查询次数,生成时间:

<?php if (is_user_logged_in()){
    echo "<pre>".get_num_queries().'次查询,用时';
    timer_stop(3);
    echo '秒</pre>';
?>

 

这个代码网络上到处都是,相信很多人都添加的有。网站加Redis之前,网页的查询次数都是150+次,生成时间2-3秒,甚至更多。用上之后减少到50+次,但是有时还是会需要1秒多,百思不得其解。

然后把主题代码该优化的都优化后,查询次数30+次,生成时间降到1秒左右,但是还是不太满足,所以想看看到底是执行了哪些查询,然后就在网上找到了这段代码,和上面的有些类似。

首先需要先在WordPress的根目录配置文件wp-config.php中添加保存查询的代码:

define('SAVEQUERIES', true);

 

然后也是在footer.php的网页最后部分添加打印代码:

<?php
if (current_user_can('administrator')){
    global $wpdb;
    echo "<pre>";
    print_r($wpdb->queries);
    echo "</pre>";
}
?>

 

但是添加后看了一下,差点当场去世,这样打印出来的是一个很大的多维数组,看的人眼花缭乱,重点是太长了还显示不全。将打印复制出来,拿到NotePad++里面打开,依旧显得很乱。

WordPress为anylink插件增加缓存实现方法插图

不过大概看了一下,大数组的每一个键值表示一个查询,然后一个查询数组了,第一个值是执行的SQL,第二个值是使用的时间,第三个值是调用的代码位置。其实可以用循环做一个网格,让前端显示看着方便一点,但是很懒,网上看了一下,有插件可以做到相关功能,且不用修改wp-config.php,即Debug Queries,所以就懒得自己写了,直接装了一个来进行排查。

需要注意的是,Debug Queries很久没有更新了,安装可能会报错,不过还是可以正常使用的。其实Debug Queries介绍页也推荐使用Debug Objects插件,但是试了一下Debug Queries可以用,也就懒得再试另一个插件了。

排查问题

工具准备好了,就来好好排查到底是哪里查询比较慢了。

插件装好了,再去看打印出来的查询信息,就比较清晰了。对比了一下,大部分的查询都是0.00x秒的,就是几毫秒的,但是只要涉及到wp_al_urls的查询,就会是即时甚至上百毫秒。

WordPress为anylink插件增加缓存实现方法插图1

看了一下,这个表是插件anylink的,这个插件主要是将网站上的外链全都转化成内链,点击后可以跳转到外链。

这个插件也是从建站伊始就在用了,是一个很好用的插件,但没有想到这个插件会出现慢查询。

通过上面的截图可以看到,对wp_al_urls的查询条件是网站链接,看了一下数据库,这个SQL是为了去拿到内链的slug记录:

WordPress为anylink插件增加缓存实现方法插图2

这里去查的,实际上是网页正文里的外链、各位评论大佬的网址对应的内链地址。

看了一下这个表,没想到竟然有10M的大小,接近10万条数据,而且这里查询的是al_origURL字段,看了一下,这个字段是没有索引的。

解决问题

对于MySQL的查询,能想到的优化方法就是加索引,所以直接就操作加索引,但是报错了:

WordPress为anylink插件增加缓存实现方法插图3

看报错是跟字段格式有关的,看了一下这个字段的类型是mediumtext的,这个字段是存URL的,有些URL非常的长,如果该varchar的话,可能会出问题,varchar最长255个字符。网上找了一阵子解决方案,都是说text相关的类型无法加索引。本来就对数据库索引什么的不太了解,所以只能放弃这条路。

还能想到的办法,就是看下这个查询的代码,想办法把结果存到Redis上缓存起来。至于怎么找到实际执行的代码,看了一下,直接找调用的最后一段就可以了。

WordPress为anylink插件增加缓存实现方法插图4

可以看到,两个SQL实际上是一样的,查的是同个网址,结果执行的时间竟然都比较长,所以确实得把结果缓存起来。

为了优化代码,把整个网站都作为了一个PhpStorm里的一个项目,不得不说一个好的IDE工具写起代码来是真的舒服。直接全局搜索,寻找get_slug_by_url这个函数,顺利找到了代码所在。

WordPress为anylink插件增加缓存实现方法插图5

这里有两个结果,第一个是原本的函数,已经被注释起来了,第二个是改了之后的。

可以看到这个函数就是调用$wpdb来执行SQL语句,将得到的结果再返回一下。函数比较简单,也很利于修改。

然后又找了一下WordPress如何添加缓存,结果找到一下,发现非常简单。

WordPress操作缓存

WordPress 为我们提供了使用对象缓存的函数,方便我们使用对象缓存。

wp_cache_add() :添加数据到缓存中,如果数据已存在,返回 flase

wp_cache_set() :添加数据到缓存中,如果数据已存在,会覆盖数据

wp_cache_get() :获取缓存中的数据,如果数据不存在,返回 false

wp_cache_delete() : 从缓存中删除数据

wp_cache_replace() :替换缓存中的数据,类似 wp_cache_set,但是如果数据不存在,不自动添加

wp_cache_flush():清除所有缓存

如果没有装redis缓存插件,上面的这些函数是在./wp-includes/cache.php里。如果装了Redis Object Cache等插件,就会自动增加一个./wp-content/object-cache.php文件,这些函数也会存在于这个文件中,用于存入缓存。

WordPress 对象缓存使用使用示例

$result = wp_cache_get( 'my_result' );
if ( false === $result ) {
    $result = $wpdb->get_results( $query );
    wp_cache_set( 'my_result', $result );
}

 

对anylink的get_slug_by_url函数改造

有了上面这个案例,为anylink的函数增加缓存就很方便了。示例很简单,get_slug_by_url函数本身也简单,所以改造后如下:

public function get_slug_by_url( $url ) {
    $arr_slug = wp_cache_get( $url );
    if ( false === $arr_slug ) {
        global $wpdb;
        $arr_slug = array();
        $arr_slug = $wpdb->get_row($wpdb->prepare(
            "SELECT *
        FROM " . ANYLNK_DBTB . "
        WHERE al_origURL = %s",
            $url
        ), ARRAY_A);
        wp_cache_set( $url, $arr_slug );
    }
    return $arr_slug;
}

 

因为示例和函数太契合了,所以这个函数几乎就和示例结构一样。首先去Redis获取缓存数据,获取不到就去MySQL查询,查到后再存到Redis。

检查效果

代码修改后,同步到测试服务器,访问了两次之前访问的页面,查询次数和用时都降下来了。然后看到查询次数还是有33次,其中有部分是查询wp_al_urls_index这个表的,虽然速度不慢,但是次数比较多,重复上面的方法也修改了一下相关函数,最终效果如下图:

WordPress为anylink插件增加缓存实现方法插图6

查看Redis的keys

上面改造的代码中,是拿url地址去做的key名称,那么也来看下缓存数据在Redis里的情况:

WordPress为anylink插件增加缓存实现方法插图7

上面改造的代码比较简陋,直接拿的URL做的key名称,如果URL比较短还好,如果长的话就可能出现问题,key名称其实可以做一下长度限制。

提示:Redis最好不要使用默认端口6379,除非安全做的非常好。

使用Redis时注意以下几点:

1、一定要配置强密码;

2、安全组、防火墙一定要最小范围放通Redis端口,即针对指定IP放通访问;

3、尽量不要使用默认端口。

因为Redis而导致服务器中木马病毒的保障,这边经常遇到。

总结

以前以为给WordPress配上Redis很麻烦,实际使用发现真香,建议有能力的朋友都上一下,毕竟生命不止,折腾不息。本文最主要的还是记录一下排查网页查询慢的过程和解决方法,希望能够给其他朋友提供思路。

上一篇
下一篇
联系我们

联系我们

返回顶部