原创文章,转载请注明: 转载自始终不够
本文链接地址: wordpress全栈优化
转载请注明:始终不够 » wordpress全栈优化
从最开始计算,《始终不够》个人博客上线已经有两年多了。从最开始就是使用的wordpress,最初为了丰富站内功能,使用了一箩筐的插件,首页加载基本在10s以上,期间使用xhprof做过几次优化,都不是很理想。最近抽出时间整体做了一次性能优化。首页响应时间从1s减少到20ms,并发度从2/s增加到500/s。可以说是有了质的飞跃。这里分享下这次的优化过程。
首先,确定我们要优化的组件:
- 浏览器端优化
- php端优化
- nginx优化
浏览器端优化
浏览器端优化比较简单,从减少网络流量的角度来看,我们需要使用压缩和浏览器端缓存。
启用压缩(注意放到http块中)。启动压缩后,浏览器接收到的是trunk编码,可以一边接收一边解析展示,提高前端加载效率。
gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-php image/jpeg image/gif image/png; gzip_vary on;
启用浏览器端cache,因为我很少会去修改静态文件,所以缓存时间设定为了30天。
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } location ~ .*\.(js|css)?$ { expires 30d; }
启用wp super cache后,你可以启用一个cdn域名。浏览器一半会限制对同一个域名的并发度(最多对同一个域名发起N个请求,N视浏览器而定)。你可以再解析一个域用于CDN静态缓存,或者将这些静态资源上传至七牛等CDN上。如果你的首页资源比较多,这是个不错的选择。
PHP端优化
PHP端优化需要考虑以下几个问题:
- 对象缓存
- PHP本身的执行效率
对象缓存,可以使用Redis Object Cache插件来实现,只需要简单配置即可,这里注意你需要安装redis扩展,否则这个插件无法启动。PHP本身的执行效率,可以使用Zend opcache来缓存php字节码,效果还是很明显的。同时,你需要对php-fpm做一些优化,例如启动模式,启动进程数量。由于我的vps使用的是阿里云,内存有限,配置并不是最优的。关于php-fpm的优化可以参考其他文章。
另外wordpress的插件,wp super cache,它可以极大的减少php对数据的访问,能够非常明显的提高执行效率,强烈推荐安装。
经过以上调整,首页响应时间从1s减少到40ms以内,平均在20ms左右。测试过程中发现,效果最好的是wp supser cache,对象缓存不是非常明显,但启用Redis Object Cache后,对并发有一定益处。
最近php7和hhvm都很火,php7和wordpress存在兼容问题,如果想进一步提升php的执行效率,可以考虑使用hhvm。hhvm安装过于复杂,可以考虑使用docker安装。
还可以将session存入redis中。文件session存在一个文件锁的问题,同一个用户同时发起两个请求时,由于session文件锁,这两个请求实际上在一定程序是串行的。将session放入redis能够解决这个问题,这里同样要求你安装redis扩展。配置方法非常简单,只需更改如下两个配置即可:
session.save_handler = redis session.save_path = "tcp://127.0.0.1:6379"
nginx优化
nginx的优化主要考虑缓存,尽可能的将请求拦截在nginx端,阻止没有必要的php执行。原理是使用nginx反向代理,将所有请求的响应结果都缓存起来。在缓存没有发生变化的情况下,直接返回缓存内容,无需执行php。产生的效果就是并发能力的明显提升。在使用反向代理之前,并发基本在6/s左右,启用反向代理之后,并发能够达到500/s,提升了近100倍。nginx配置过程如下:
1、在http块中添加如下两段
代理缓存配置,注意www.huyanping.cn需要换成你的域名(或者其他字符串都可以)
proxy_temp_path /tmp/nginx;
proxy_cache_path /tmp/cache/nginx levels=1:2 keys_zone=www.huyanping.cn:20m max_size=1g inactive=1d;
upstream配置
upstream backend_server {
server 127.0.0.1:8080 weight=1 max_fails=2 fail_timeout=30s;
}
2、代理服务器配置
80端口用于做反向代理,8080端口是真实的server
server { listen 80; server_name www.huyanping.cn huyanping.cn; location / { proxy_pass http://backend_server; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_cache www.huyanping.cn; proxy_cache_valid 200 302 12h; proxy_cache_valid 301 1d; proxy_cache_valid any 1h; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; } }
真实server配置
server { listen 8080; server_name www.huyanping.cn huyanping.cn; index index.php index.html index.htm; root /alidata/www/private/www.huyanping.cn/; #charset koi8-r; error_page 403 = /404.html; error_page 404 = /404.html; location / { if (-f $request_filename/index.html){ rewrite (.*) $1/index.html break; } if (-f $request_filename/index.php){ rewrite (.*) $1/index.php; } if (!-f $request_filename){ rewrite (.*) /index.php; } } location ~ \.php$ { add_header Access-Control-Allow-Origin http://cdn.huyanping.cn; if ( $request_method = HEAD ) { access_log /dev/null; return 403; } fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; access_log /data/logs/nginx/www.huyanping.cn/access.log blog; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { add_header Access-Control-Allow-Origin http://cdn.huyanping.cn; expires 30d; } location ~ .*\.(js|css)?$ { add_header Access-Control-Allow-Origin http://cdn.huyanping.cn; expires 30d; } }
效果截图
ab测试结果
> ab -n100 -c10 "http://www.huyanping.cn/" This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright 2006 The Apache Software Foundation, http://www.apache.org/ Benchmarking www.huyanping.cn (be patient).....done Server Software: nginx Server Hostname: www.huyanping.cn Server Port: 80 Document Path: / Document Length: 0 bytes Concurrency Level: 10 Time taken for tests: 0.193371 seconds Complete requests: 100 Failed requests: 0 Write errors: 0 Non-2xx responses: 100 Total transferred: 32200 bytes HTML transferred: 0 bytes Requests per second: 517.14 [#/sec] (mean) Time per request: 19.337 [ms] (mean) Time per request: 1.934 [ms] (mean, across all concurrent requests) Transfer rate: 160.31 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 4 8 7.5 5 32 Processing: 4 9 8.1 6 31 Waiting: 4 8 8.2 5 30 Total: 8 17 10.2 12 38 Percentage of the requests served within a certain time (ms) 50% 12 66% 14 75% 32 80% 32 90% 34 95% 36 98% 38 99% 38 100% 38 (longest request)
没能解决的问题
最初用ab测试,发现www.huyanping.cn的并发度非常低,基本在2/s左右,而wordpress裸跑基本能跑到300/s,调试了很久最终都没找到原因所在。虽然最终使用反向代理将并发度优化到500/s,但还是不甘心想找到原因。最初怀疑有文件锁存在,使用xhprof分析及阅读代码之后,并没有找到锁的存在,当然可能是我没找到。最终把原因归结在数据访问效率上,虽然有点牵强。
不知道有木有大牛可以帮忙分析下这个原因?