从能用到好用-快速搭建高性能WordPress指南

admin

本文最后更新于 2021年03月10日

注意:本文的所有代码都可以不用看,有一键启动的 docker-compose.yml文件,直接拖动到文章最后即可下载配置文件

前言

之前已经写过几篇WordPress性能优化文章了,但是还不够。面对访问量大的情况下还是有可能发生宕机,没办法服务器资源有限又跑了不少其他服务

如果想要再继续降低资源使用率,就要从根源下手了

博主的服务器基本信息

博主目前使用的服务器性能低下,2C1G。跑了多个服务,资源吃紧,特别是内存。为了提升稳定性,使用了大量swap,降低内存占用就成了首要工作

优化思虑

首先要整理一下优化思路

目前最占用内存的应用就是MySQL,所以要降低内存使用首先就要调整MySQL参数。不过MySQL的内存降下去了,但是数据库查询使用的CPU反倒没有降低,这时候可以通过加入Redis做缓存来提升性能。

WordPress自身也很耗费CPU和内存,这块可以通过静态化解决,理清思路就可以着手优化了

优化措施

前面已经理清了优化思路,剩下的就是动手操作和测试了

不过如果要方方面面都讲清楚很难,我就直接上docker-compose.yml和配置文件了,这套方案经过长期的的使用,足够稳定,大家可以直接一键部署

MySQL 5.7 内存占用优化

MySQL 5.5的资源占用情况还算不错,但是太老旧了,WordPress官方推 MySQL 5.7

优化 MySQL 5.7 的内存占用非常简单,编辑/etc/mysql/mysql.conf.d/mysqld.cnf,在[mysqld]下方添加如下代码即可

博主的MySQL从200M+降低到80M,效果非常明显

[mysqld]# Memory optimizationperformance_schema_max_table_instances=200table_definition_cache=100table_open_cache=100

Redis缓存

使用Redis做数据库缓存,能够有效减少MySQL的查询次数



NGINX Fastcgi 缓存

常见的WordPress缓存形式我之前已经介绍过,想要了解的可以参考之前的文章

这次介绍的是性能更好的NGINX缓存,由于需要编辑NGINX文件,对于新手来说过于复杂,具体的我就不过多讲解了,配置文件注释都写了,想了解的可以自己翻看

使用NGINX Fastcgi后,访问文章页面从60~90%的CPU占用率降低到个位数,效果拔群

注1:原本的NGINX是没有Fastcgi 缓存清理模块的,我编译了一份带有缓存清理模块的NGINX,并封装了docker image

注2:使用 NGINX Fastcgi缓存 需要安装WordPress插件 Nginx-Helper

注3:目前nginx-helper无法清除中文url的文章缓存(不太确定,在本地调试时可以清除中文url路径的缓存,但是生产环境却不行,英文路径可以),已经向作者提issue了,不过估计不会被理会,如果有大手子知道怎么改请务必告诉我,谢谢

2021.03.05更新
读一下nginx-helper的源码,关于cache_path的获取,是通过对url进行hash,这段内容在class-purger.php中

// Build a hash of the URL.$hash = md5( $url_data['scheme'] . 'GET' . $url_data['host'] . $url_path );// 这块以下都不用管// Ensure trailing slash.$cache_path = RT_WP_NGINX_HELPER_CACHE_PATH;$cache_path = ( '/' === substr( $cache_path, -1 ) ) ? $cache_path : $cache_path . '/';// 设置缓存路径,如果和nginx生成的缓存路径不匹配。则无法删除缓存// Set path to cached file.$cached_file = $cache_path . substr( $hash, -1 ) . '/' . substr( $hash, -3, 2 ) . '/' . $hash;

由于生成的md5对不上,经过一番调试,我发现是url地址获取有误,并非大小写问题,根据nginx的配置和生成的key,可以得知,key如何生成的,逐个测试就好了,我的情况是,经过反代或cloudflare后,$url_data['host']获取有误,所以手动填写前半段即可,并且path必须改为双引号,单引号不行

// Build a hash of the URL.
$hash = md5( 'httpGETsleele.com' . $url_data["path"] );

// Ensure trailing slash.
$cache_path = RT_WP_NGINX_HELPER_CACHE_PATH;
$cache_path = ( '/' === substr( $cache_path, -1 ) ) ? $cache_path : $cache_path . '/';

// Set path to cached file.
$cached_file = $cache_path . substr( $hash, -1 ) . '/' . substr( $hash, -3, 2 ) . '/' . $hash;
可选项:修改缓存位置
例:
缓存位置请编辑,wp-config.php 添加
define( 'RT_WP_NGINX_HELPER_CACHE_PATH','/tmp/wpcached');

或 编辑Nginx-Helper代码 class-nginx-helper.php ,修改路径为
define( 'RT_WP_NGINX_HELPER_CACHE_PATH','/tmp/wpcached');
server {
listen 80 ;
listen [::]:80;

root /var/www/html;

# Add index.php to the list if you are using PHP
index index.php;
server_name _;

set $skip_cache 0;
# post 访问不缓存
if ($request_method = POST) {
set $skip_cache 1;
}
# 动态查询不缓存
if ($query_string != "") {
set $skip_cache 1;
}
# 后台等特定页面不缓存(其他需求请自行添加即可)
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml|nginx.log") {
set $skip_cache 1;
}
# 对登录用户、评论过的用户不展示缓存(建议禁用登录和评论用户的缓存,不要删除这里面的内容就对了,默认设置非常合理)
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
set $skip_cache 1;
}
# 不要乱改ip地址
location ~ [^/]\.php(/|$) {
try_files $uri =404;
fastcgi_pass    172.19.0.4:9000;
fastcgi_index   index.php;
include         fastcgi.conf;
# 获取真实IP
set_real_ip_from 172.19.0.0/16;
real_ip_header  X-Forwarded-For;
real_ip_recursive   on;
# 新增的缓存规则
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
add_header X-Cache "$upstream_cache_status From $host";
fastcgi_cache WORDPRESS;
fastcgi_cache_valid 200 301 302 304 1d;
fastcgi_cache_valid 404 10m;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
# 缓存清理配置(可选模块,请细看下文说明)
location ~ /purge(/.*) {
allow 127.0.0.1;
# 默认是所以人都可以清理缓存,设置为只能自己清理,请把下面的ip段改为自己服务器的ip
allow 172.19.0.0/16;
deny all;
fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";
}

location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
access_log off;
log_not_found off;
expires max;
}
location = /robots.txt {
access_log off;
log_not_found off;
}
location ~ /\. {
deny  all;
access_log off;
log_not_found off;
}

}

其他优化措施

往期文章


将NGINX缓存放入内存盘

非常简单

将缓存位置挂载到宿主机的/dev/shm/路径即可- /dev/shm/nginx-cache:/var/run/nginx-cache

使用WEBP替换JPG、PNG

这个以后单独再写一篇,jpg,png转换到webp的性能需求太高了,上传一张图片需要很久,cpu还会被占满,性能低的机器用不起,目前的我构想是:把图片提前转换成webp,然后使用GitHub Action定期转换仓库的图片,但是实施起来没有预想的简单,外链图片不知道怎么自动选择,webp express插件没有产生效果

https://hub.docker.com/r/webpsh/webps

一键部署高性能WordPress

注:请先安装docker和docker-compose

我估计大部分人应该都不愿意在性能优化这块折腾太多,毕竟不是每个人都懂WordPress和相关工具的配置(我自己也不是很懂),WordPress是拿来写作的,专注写作最重要

下载wordpress-blog.zip,解压后拖到服务器,进入到 wordpress-blog 目录,docker-compose up -d 启动即可

使用前最好改一下数据库的密码ip请不要改动,除非你明确知道你在做什么所有生成数据均在wordpress-blog文件夹中默认最大上传文件2GB
version: '3.1'

services:

wordpress:
image: wordpress:5-fpm
restart: always
networks:
wordpress_net:
ipv4_address: 172.19.0.4
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
volumes:
- /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
- $PWD/wordpress:/var/www/html
# - /dev/shm/nginx-cache:/var/run/nginx-cache
- $PWD/nginx-cache:/var/run/nginx-cache
- $PWD/nginx/uploads.ini:/usr/local/etc/php/php.ini
depends_on:
- redis
- db

redis:
image: redis:5
restart: always
networks:
wordpress_net:
ipv4_address: 172.19.0.3
volumes:
- /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
- $PWD/redis-data:/data
depends_on:
- db

db:
image: mysql:5.7
restart: always
networks:
wordpress_net:
ipv4

1.327923s