最近一直在整理网站的代码,试图加快网站的速度,主要是从代码、软件和网络方面,都是从网站切换到HTTPS开始的。
已经连续观察CDN多天了,现在是检查缺口和陷阱的时候了。目前也把整个网站备份到另一个服务器,把网站解析到这个服务器本地,开始查代码。调试已打开,一些大问题已得到处理。然后对主题的代码进行了整理,网站还增加了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++里面打开,依旧显得很乱。
但是,简单看一下,大数组的每个键值代表一个查询,然后出现一个查询数组。第一个值是执行的SQL,第二个值是使用的时间,第三个值是调用代码的位置。其实我们可以做一个带循环的格子,让前端显示看起来更方便,但是比较懒。在线检查后,有一些插件可以在不修改wp-config.php的情况下执行相关功能,即调试查询。所以仙森懒得自己写,就装了一个来排除故障。
需要注意的是,Debug Queries已经很久没有更新了,安装可能会报错,但仍然可以正常使用。其实Debug query的介绍页面也推荐使用Debug Objects插件,但是先试了Debug query之后,就懒得再试别的插件了。
疑难解答问题
当工具准备好了,就会来找出查询到底慢在哪里。
插件安装好之后,看打印出来的查询信息会更清晰。森先比较了一下。大部分的查询都是0.00x秒,也就是几毫秒,但只要涉及到wp _ al _ urls的查询,就会是瞬间甚至几百毫秒。
Wp _ al _ urls查询-2
wp _ al _ urls的查询
看了一下。这个表属于插件anylink。这个插件主要是把网站上所有的外链转换成内链。单击后,您可以跳转到外部链。
对于anylink,也在这里发了两篇相关文章:
WordPress为anylink插件的跳转添加了一个漂亮的跳转页面。
WPJAM BASIC插件与任何链接冲突
这个插件从网站建起就一直在用。这是一个非常有用的插件,但是我没想到这个插件的查询速度会很慢。
从上面的截图可以看到,wp _ al _ urls的查询条件是网站链接。看看数据库。这个SQL是为了得到内链的slug记录:
Anylink获得slug -3
任何链接都会被删除
我在这里查找的其实是网页主体中的外部链接,以及每个评论老板的网址对应的内部链接地址。
看了一下表,没想到是10M大小,接近10万条数据,这里查询的是al _ origURL字段。看了一下,这个字段没有索引。
解决问题
对于MySQL查询,能想到的优化方法就是添加索引,所以仙森直接操作添加索引,但是报错了:
索引al _ origURL字段时出现错误-4
索引al _ origURL字段时出错
错误报告与字段的格式有关。看看这个字段的类型,它是mediumtext。此字段用于存储网址。有些网址很长。如果是varchar,可能会有问题。varchar长度为255个字符。我在网上搜索了一段时间的解决方案,所有这些都意味着与文本相关的类型无法索引。对数据库索引了解不多,只好放弃这条路。
能想到的第一种方法是查看这个查询的代码,并找到一种方法将结果保存到Redis进行缓存。至于如何找到实际执行的代码,先看了一下,直接找调用的最后一段就行了。
如您所见,这两个SQL实际上是相同的。他们在查找同一个URL,但是结果的执行时间实际上更长,所以我们真的要缓存结果。
为了优化代码,仙森在PhpStorm中将整个网站作为一个项目,不得不说一个好的IDE工具写代码真的很舒服。直接全局搜索,寻找get_slug_by_url的函数,成功找到代码。
搜索get_slug_by_url函数-6
搜索get_slug_by_url函数
这里有两个结果。第一个是原函数,已经被仙森注释了,第二个是仙森修改后的。
可以看到,这个函数是调用$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文件,这些函数也会存在于这个文件中存储在缓存中。
对象缓存使用示例
$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函数改造
any link 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。
提示:Redis最好不要使用默认端口6379,除非安全性非常好。
使用Redis时要注意以下几点:
1.请务必配置强密码;
2.安全组和防火墙必须在最小范围内让Redis端口通过,即让通过访问指定的IP;
3.尽量不要使用默认端口。
由于Redis的存在,仙森经常会遇到服务器中的木马病毒防护。
摘要
一开始觉得给WordPress加Redis很麻烦。在实践中,他发现它真的很香。他建议所有有能力的朋友都去看看。毕竟,生命是无穷无尽的。本文最重要的是记录慢网页查询的过程和解决方法,希望能为其他朋友提供思路。