优化配置Wordpress和Nginx降低服务器响应时间,最便宜服务器跑多插件大模板网站

2018-09-10 约 2464 字 预计阅读 5 分钟

昨天儿子按照前面我写的教程作出了人生第一个博客,教程参见八步教程 – 从零基础到2小时建立Google PageSpeed Insights100分、安全度A级的博客站点平台

接下来的问题虽然他还没有遇到,但我却早有先见。

因为打算服务器的费用由他自己想办法赚钱支付,目前让他采购的是Vultr最便宜的服务器,3.5美金每月,1个CPU,内存只有512MB的最mini型服务器。

而wordpress是非常吃内存的CMS系统,区区512MB估计过不几天增加几个插件和模板,服务器的响应时间可能就不能满足Google Speed Insights的要求了。

就如我本人这个博客,初始的时候速度不慢,但使用了DIVI,增加了不少其他插件后,在Google Speed Insights的测试结果,服务器响应时间就超过了200ms,速度也明显可以肉眼看到非常慢。

网速是网站之本,这个必须要解决,经过一番google,找到了解决方案,为了给儿子做一个参考,还是用fxdiary.com走一遍。

 

本解决方案部分参考了Howtoforge的帖子Configuring Your LEMP System (Linux, nginx, MySQL, PHP-FPM) For Maximum Performance 感谢互联网。

不过该帖是数年前写就,主要针对PHP5,今次教程本人用PHP7.2一步步验证,亲测有效

还是老规矩,如果需要你自己修改的地方,本帖会红色注明。

 

降低服务器硬盘不必要的读写要求


好首先远程登录fxdiary.com服务器
ssh jesse@fxdiary.com

为mount选项添加noatime和nodiratime,这是为了降低硬盘读写率,命令如下:
sudo nano /etc/fstab

打开文件后,找到
errors=remount-ro 0 1

将之修改为红色部分
errors=remount-ro,noatime,nodiratime,usrjquota=quota.user,grpjquota=quota.group,jqfmt=vfsv0 0 1

存盘退出,再运行
sudo mount -o remount /

配置nginx conf文件


运行下列命令编辑nginx.conf文件
sudo nano /etc/nginx/nginx.conf

如下修改
http {
...
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 2;
types_hash_max_size 2048;
server_tokens off;
...
}

keepalive_timeout从缺省值65秒改为更合理的2秒

开启文件的缓存
http {
...
##
# File Cache Settings
##

open_file_cache max=5000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
...
}

开启ssl-session的缓存
http {
...
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;

...
}

开启fastCGI 缓存
http {
...
## Nginx FastCGI Cache
fastcgi_cache_path /var/cache/nginx/ levels=1:2 keys_zone=cachezone:10m max_size=2g inactive=60m;
fastcgi_cache_key $scheme$request_method$host$request_uri;
fastcgi_cache_lock on;
fastcgi_cache_revalidate on;
fastcgi_cache_background_update on;
fastcgi_cache_use_stale error timeout invalid_header updating http_500;
fastcgi_cache_valid any 60m;
fastcgi_pass_header Set-Cookie;
fastcgi_pass_header Cookie;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

...
}

/var/cache/nginx/缓存目录必须存在,而且要有权限写入,所以存盘退出后,要运行下列命令
sudo mkdir /var/cache/nginx

sudo chown www-data:www-data /var/cache/nginx

这样nginx.conf就修改完了,我这里贴上fxdiary.com的nginx.conf全文供参考
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
worker_connections 768;
# multi_accept on;
}

http {

##
# Basic Settings
##

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 2;
types_hash_max_size 2048;
server_tokens off;

# server_names_hash_bucket_size 64;
# server_name_in_redirect off;

open_file_cache max=5000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
include /etc/nginx/mime.types;
default_type application/octet-stream;

##
# SSL Settings
##
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;

##
# Logging Settings
##

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

##
# Gzip Settings
##

gzip on;

gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

##
## Nginx FastCGI Cache
fastcgi_cache_path /var/cache/nginx/ levels=1:2 keys_zone=cachezone:10m max_size=2g inactive=60m;
fastcgi_cache_key $scheme$request_method$host$request_uri;
fastcgi_cache_lock on;
fastcgi_cache_revalidate on;
fastcgi_cache_background_update on;
fastcgi_cache_use_stale error timeout invalid_header updating http_500;
fastcgi_cache_valid any 60m;
fastcgi_pass_header Set-Cookie;
fastcgi_pass_header Cookie;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
# Virtual Host Configs
##

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}

配置虚拟主机的文件


运行
sudo nano /etc/nginx/sites-available/fxdiary.com

增加fastcgi的缓存功能,但需要设置成登录进wordpress编辑模式时不缓存
location ~ \.php$ {

include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

set $skip_cache 0;
# POST requests and url's with a query string should always skip cache
if ($request_method = POST) {
set $skip_cache 1;
}
if ($query_string != "") {
set $skip_cache 1;
}
# Don't cache url's containing the following segments
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
set $skip_cache 1;
}
# Don't use the cache for logged in users or recent commenters
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
set $skip_cache 1;
}
# (for some reason, add_header fails if included in prior if-block)
if ($skip_cache = 1) {
add_header Set-Cookie "_mcnc=1; Max-Age=2; Path=/";
add_header X-Microcachable "0";
}
# Bypass cache if no-cache cookie is set
if ($http_cookie ~* "_mcnc") {
set $skip_cache 1;
}

fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
fastcgi_cache cachezone;
include fastcgi_params;
fastcgi_buffer_size 128k;
fastcgi_connect_timeout 60s;
fastcgi_send_timeout 60s;
fastcgi_read_timeout 60s;
fastcgi_buffers 256 16k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
}

这样/etc/nginx/sites-available/fxdiary.com的全文如下:
server {
listen 80;
listen [::]:80; ## listen for ipv6

server_name fxdiary.com www.fxdiary.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl; # managed by Certbot
server_name fxdiary.com www.fxdiary.com;

root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
location = /favicon.ico { log_not_found off; access_log off; }
location = /robots.txt { log_not_found off; access_log off; allow all; }
location ~* \.(css|gif|ico|jpeg|jpg|js|png|woff)$ {
expires max;

log_not_found off;
}
location / {

try_files $uri $uri/ /index.php$is_args$args;
}

location ~ \.php$ {

include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

set $skip_cache 0;
# POST requests and url's with a query string should always skip cache
if ($request_method = POST) {
set $skip_cache 1;
}
if ($query_string != "") {
set $skip_cache 1;
}
# Don't cache url's containing the following segments
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
set $skip_cache 1;
}
# Don't use the cache for logged in users or recent commenters
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
set $skip_cache 1;
}
# (for some reason, add_header fails if included in prior if-block)
if ($skip_cache = 1) {
add_header Set-Cookie "_mcnc=1; Max-Age=2; Path=/";
add_header X-Microcachable "0";
}
# Bypass cache if no-cache cookie is set
if ($http_cookie ~* "_mcnc") {
set $skip_cache 1;
}

fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
fastcgi_cache cachezone;
include fastcgi_params;
fastcgi_buffer_size 128k;
fastcgi_connect_timeout 60s;
fastcgi_send_timeout 60s;
fastcgi_read_timeout 60s;
fastcgi_buffers 256 16k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
}

location ~ /\.ht {
deny all;
}

ssl_certificate /etc/letsencrypt/live/fxdiary.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/fxdiary.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

}

PHP-FPM紧急情况设置


假如突然当机了,php可以自动重启。运行命令
sudo nano /etc/php/7.2/fpm/php-fpm.conf

将emergency的设置更改为如下:
; If this number of child processes exit with SIGSEGV or SIGBUS within the time
; interval set by emergency_restart_interval then FPM will restart. A value
; of '0' means 'Off'.
; Default Value: 0
emergency_restart_threshold = 10

; Interval of time used by emergency_restart_interval to determine when
; a graceful restart will be initiated. This can be useful to work around
; accidental corruptions in an accelerator's shared memory.
; Available Units: s(econds), m(inutes), h(ours), or d(ays)
; Default Unit: seconds
; Default Value: 0
emergency_restart_interval = 1m

CTRL-X存盘退出。

降低网络开销,将TCP更换为UNIX的socket.


运行下列命令
sudo nano /etc/php/7.2/fpm/pool.d/www.conf

打开www.conf文件后找到如下语句,更改为红色标注部分
; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions.
; Default Values: user and group are set as the running user
; mode is set to 0660
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

改成socket方式后,可能会经常遇到502错误,需要增加每个socket的连接数。运行下列命令
sudo nano /etc/sysctl.conf

打开文件后在最后一行加上
net.core.somaxconn = 4096

CTRL-X存盘退出,然后运行如下命令激活
sudo sysctl -p

至此全部配置完成,运行下列命令重启php和nginx
sudo service php7.2-fpm restart

sudo service nginx restart


检查成果


到Google Pagespeed Insights检查一下,“Reduce server response time”的优化建议已经没有了。

加了fastCGI cache的设置,网站速度大幅增加,用pingdom再测试本站,用了商业模板divi,加了许多重型的插件,网速仍然没有太大影响,重要的是,现在本站也只是用的5美元每月的次低配置服务器。



更新:对于我们经常更新帖子的博客来说,用cache也是有双刃剑的,常常发表完后只是初稿,修修改改是常有的,但是cache会保存了原有的帖子,对用户而言,在一定时限内是看不到更新版的。

每次更新帖子,需要删除缓存。对我们这个配置而言就是登录到远程服务器后运行:
sudo rm -rf /var/cache/nginx/*

那能不能自动实现,编辑完帖子自动去删除缓存?

还是那句老话,互联网从来不缺乏高风亮节者,又找到一个免费插件。Nginx Cache

设置也很简单,将我们的cache目录贴上就好了。



好了,编辑好了存盘,用其他设备打开看这个帖子,更新了。说明插件无问题。

以后就可以安心的编辑修改,而不用烦恼缓存清除的事情了。这就是“自动化”的好处。

 

author

Jesse Lau

网名遁去的一,简称遁一。2012年定居新西兰至今,自由职业者。
本文采用知识共享署名 4.0 国际许可协议进行许可。简而言之,可随意转发转载,转载请注明出处。


留点评论吧:

本网站使用cookie技术以提高用户体验度。 了解我们的隐私政策 我已了解