WordPress建站心得(二)网站架构设计

在上一篇文章《WordPress建站心得(一)前端性能优化》中,我们提到了如何在服务器和网络状况不变的情况下,通过调整优化请求数目和顺序,缩短页面呈现时间,从而提升用户体验。不过,这种优化只是在请求之间的优化,它并不能提升每个请求的响应时间,如果需要继续优化性能,则必须从服务器和网络本身入手。

我们谈到服务器性能,主要有三个比较重要的衡量标准。一是吞吐量,表示网站在一定时间内能有效承载的请求的最大数量,也就是网站能承受多少人同时访问。二是资源消耗,表示网站在处理一定数量的请求时,所消耗的服务器资源,这和网站的成本直接挂钩。三是首包时间,表示网站返回动态(如PHP, JSP)与静态请求(如js,css,jpg)所需要的计算时间。

在这三个标准中,传统的性能优化主要集中在头两个方面,这无可厚非,因为直接涉及到网站的运营成本和覆盖范围。诚然,这三个标准其实相互作用,一个性能优良的网站,必然会有较高的吞吐量,较低的资源消耗,以及较低的首包时间。不过这并非完全正确,因为采用传统方法优化服务器架构,只能在前两方面有所进步。比如,采用web–>application–>db三层服务器集群,中间通过load balancer来动态调配,的确能极大增加吞吐量和降低单服务器资源消耗,但首包时间并不会因此而大大降低,反而会因为服务器之间的网络沟通产生延时。

回到WordPress的例子上面,相信很多站长都和我一样,没有充裕的budget,只是凭个人爱好而建站,必然没有那么多资源建设庞大的服务器集群,但我们同样有很多办法优化我们仅有的vps性能,从而降低首包时间,减少资源消耗,增大吞吐量。这篇文章针对的正是我们这些草根站长。

首先,让我们回顾一下,一个网站是如何向用户展示信息的,以WordPress为例。

  1. 用户浏览器准备发送请求
  2. 系统从DNS缓存中解析出服务器IP
  3. 如DNS缓存中没有,则通过DNS请求向上级DNS服务器逐步请求,直至获得IP(可选)
  4. 浏览器同服务器建立连接
  5. 如果是SSL连接,则浏览器同服务器进行SSL Handshake(可选)
  6. 浏览器向服务器发送请求
  7. 服务器的Web Server(如Apache, Nginx)收到请求,判断是否为动态请求
  8. 如果是静态请求,从硬盘中读取相应文件,返回给浏览器
  9. 如果是动态请求,将该请求交由PHP模块或独立PHP进程处理
  10. PHP程序收到处理请求,从硬盘中读取相应的PHP文件
  11. PHP程序将PHP文件从源码编译为Opcode
  12. PHP程序执行Opcode
  13. 如果需要DB操作,则PHP程序向MySQL Server发出查询请求(可选)
  14. MySQL Server从硬盘中读取数据库,进行查询,返回结果(可选)
  15. PHP将生成的HTML返回给Web Server
  16. Web Server将HTML返回给用户浏览器
  17. 用户浏览器解析HTML,展示页面,同时准备下一个请求

看着都头晕,如果你的服务器返回每一个动态页面都需要经历这十几个步骤,首包时间怎么可能短的了呢?所以,必须进行优化。

以下将根据以上过程的顺序逐一介绍优化的技术。注意:并不是每个技术都适用于所有网站,本文仅供参考。站长应知晓调整架构所带来的风险。照以下方法进行优化所带来的一切后果本人概不负责。

DNS缓存

一般情况下,用户访问的第一站就是你的DNS了。DNS负责将你的域名转换成IP,如果设计不当,将大大拖慢用户首次访问所需的时间。

1. DNS运营商选择

如果网站的目标用户群在国外,则GoDaddy等自带的DNS就不错。不过如果目标用户群在国内,则需要用国内的DNS运营商,如DNSPod等。考虑DNS运营商时,一定要看清楚其DNS的分布节点。当然是越多越好。这里为避免广告嫌疑,就不做推荐了。

2. DNS解析类型

一般解析类型为A,AAAA (IPV6),CNAME几种。如果可能,尽量避免使用CNAME,而使用A记录,因为CNAME记录会让DNS解析多解析一两个其他域名,加大延时。另外一定要注意CNAME记录不要放在@,否则会和MX记录冲突,导致邮件接收失败。

3. 记录过期时间(TTL)

这个设置对提升DNS解析速度至关重要。全球各地的运营商会在自己的DNS服务器上设置缓存,而决定缓存失效的时间就是TTL。如果设置了TTL,则同一地区的其他人再次访问DNS的时候,就会直接从本地的DNS获取结果,不用再经历漫长的DNS查询。不过,TTL设置得太长,则会影响灵活性,比如要更改DNS设置的时候,需要更长的时间才能让全球各地的用户更新。一般建议没有太大变动的DNS设置为86400秒,也就是一天,如果要更改DNS设置,则提前一天将TTL改成300或更少。设置好之后,在站长工具检测一下就知道是否成功了。

内容分发网络(CDN)

CDN是一种服务,将你网站的内容通过其他的服务器分发,降低Ping值,减少连接时间。有的CDN支持将html整个缓存,从而减少服务器压力。

1. 究竟需不需要CDN?

这个问题放在以前,我肯定毫不犹豫地说需要,不过在权衡了价格和效果后,我的看法是,It depends。如果你的网站真的有成千上万人从全国各地甚至全世界各地访问,而你恰好又有充足的预算,那就可以有。不过如果只是一个中小型网站,像我这种个人博客,那就得具体看服务器的位置和提供的服务了。如果你的网站架设在百度云、阿里云或者新浪云上,恭喜你,你不需要CDN,因为这些平台本身就是分布式的,从全国各地访问速度差不多。如果架设虚拟空间或者VPS,且域名已经备案,可以尝试用加速乐等免费的CDN。如果域名没有备案,那么国内许多CDN用不了,或者只能用国外节点,我建议不要用CDN,因为即使从内地访问到CDN所用时间不多,CDN连接你的服务器也需要很长时间,所以综合算下来还是不值得。当然,如果你有预算,上Akamai或者ChinaCache,就另当别论了。

2. CDN全页缓存

有一些CDN提供了页面缓存功能,意图是不错的,不过一定要注意对Log-in用户的处理,我曾经用Google Pagespeed当CDN用,但它会连一些只有管理员才能看到的元素都缓存下载,带来安全隐患。所以,如果CDN不能提供缓存的微调功能,不要随意开启全页缓存。

3. CDN的永远在线功能

很多CDN提供了永远在线功能,说白了就是在你的源服务器无法访问的情况下,为终端用户显示一个漂亮的维护页面。这样做可以提高用户体验。

关于CDN就谈这么多,Alex Sky前前后后也试过不少CDN,但最后终因效果不佳、稳定性不高而放弃。等以后真的有了很多很多访客的时候,再考虑添加CDN吧。

服务器连接优化

服务器连接方面可调整的并不多,主要是KeepLive的设置,在返回的标头上应加上

Connection: Keep-Alive

这样浏览器在连接到服务器后,发送的其他请求就不需要重新连接,从而加快响应。

缓存代理

缓存代理布置在Web Server之前,缓存所有请求,并直接响应新的请求,从而大大提高响应速度。缓存代理对性能提升的影响非常大,因此我强烈建议采用。采用缓存代理后,上面所述的请求处理步骤,在第六部的时候就可以得到完整地html应答,省去了后面繁杂的步骤。缓存代理的代表是Varnish。

本文不会详细介绍Varnish的安装。如果你是Debian平台,可以参考这篇指南。如果是RedHat系,可以参考这篇指南。

以下分享一下Alex Sky所用的Varnish配置,配置文件在/etc/varnish/default.vcl目录

# 导入standard module设置自定义错误页面
import std;

backend default {
    .host = "127.0.0.1";
    .port = "%backend webserver port%";
}

acl purge {
    "127.0.0.1";
    "%public_ip%";
}

sub vcl_recv {
  if (req.request == "PURGE") {
    if (!client.ip ~ purge) {
      error 405 "Not allowed.";
    }
    return (lookup);
  }

  if (req.url ~ "\.(gif|jpg|jpeg|swf|css|js|flv|mp3|mp4|pdf|ico|png)(\?.*|)$") {
    unset req.http.cookie;
    set req.url = regsub(req.url, "\?.*$", "");
  }

  if (req.url ~ "\?(utm_(campaign|medium|source|term)|adParams|client|cx|eid|fbid|feed|ref(id|src)?|v(er|iew))=") {
    set req.url = regsub(req.url, "\?.*$", "");
  }

  if (req.url ~ "wp-(login|admin)" || req.url ~ "preview=true" || req.url ~ "xmlrpc.php") {
    return (pass);
  }

  if (req.request == "POST" && req.url ~ "wp-comments.php") {
    ban("req.url == " + req.url);
    return(pass);
  }

  if (req.http.cookie) {
    if (req.http.cookie ~ "(wordpress_|wp-settings-)") {
      return(pass);
    } else {
      unset req.http.cookie;
    }
  }
}

# 缓存页面30天
sub vcl_fetch {
  if ( (!(req.url ~ "(wp-(login|admin)|login)")) || (req.request == "GET") ) {
    unset beresp.http.set-cookie;
    set beresp.ttl = 30d;
  }

# 缓存静态资源一年
  if (req.url ~ "\.(gif|jpg|jpeg|swf|css|js|flv|mp3|mp4|pdf|ico|png)(\?.*|)$") {
    set beresp.ttl = 365d;
  }
}

sub vcl_deliver {
# multi-server webfarm? set a variable here so you can check
# the headers to see which frontend served the request
#   set resp.http.X-Server = "server-01";
   if (obj.hits > 0) {
     set resp.http.X-Cache = "HIT";
   } else {
     set resp.http.X-Cache = "MISS";
   }

# 除去没必要的回应标头
   remove resp.http.X-Powered-By;
   remove resp.http.Via;
   remove resp.http.X-Varnish;
   remove resp.http.Age;
   remove resp.http.X-Cache;
   remove resp.http.X-W3TC-Minify;
}
sub vcl_hit {
  if (req.request == "PURGE") {
    purge;
    error 200 "OK";
  }
}

sub vcl_miss {
  if (req.request == "PURGE") {
    purge;
    error 404 "Not cached";
  }
}

# 设置自定义错误页面
sub vcl_error {
  set obj.http.Content-Type = "text/html; charset=utf-8";
  synthetic std.fileread("%errorpage%");
  return(deliver);
}

注意替换%变量%

%backend webserver port%替换为你的backend webserver的开放端口,设置Varnish后,80端口被Varnish占用,你需要为Apache或Nginx配置另外一个内部端口作为侦听端口

%public_ip%替换为你的服务器的ip地址

%errorpage%替换为你自定义的报错页面的绝对路径,比如/var/www/error.html

下图是Alex Sky使用了Varnish后的响应时间图。

varnishcache

可以看到,在200个虚拟用户疯狂不间断点击的情况下,响应时间仍然在80ms以下,吞吐量至少有63544/min,而短短一分钟内,Varnish响应了3.17GB的内容,没有任何错误!

SSL连接优化

如果你的站点开启了SSL,就会发现连接速度大大降低。这是因为每一次连接都涉及到SSL Handshake的步骤。其实这一部分也是可以通过优化来减少连接时间的。

1. 采用ECDHE Cipher Suite

ECDHE是近年来流行的Cipher Suite,可以实现Perfect Forward Secrecy,至于对安全的作用我将在下一篇文章中着重阐述。这篇文章主要讲讲对性能的影响。目前支持PFS的Cipher Suite只有两种,DHE和ECDHE。如果使用DHE,会很大程度上影响性能,所以建议采用ECDHE。目前版本的Nginx支持,而Apache则需要升级到2.4才能支持。

2. 开启SPDY协议

SPDY是Google近年来推行的一个新的协议。目前建立在SSL上,是为了优化已经沿用十几年的HTTP/1.1标准,SPDY协议的介绍可以看月光博客或者Google官方说明。SPDY目标是提高HTTP响应速度50%。SPDY和HTTP/2.0将成为下一代互联网的基础。SPDY目前的版本号是SPDY/3.1,只有Google的服务器支持,Apache可以使用的版本是SPDY/3,而Nginx使用的是SPDY/2。因为奇奇怪怪的原因,SPDY目前仅支持Apache2.2,虽然官方说会尽快支持2.4,不过现在做的也只有等。所以对于Apache来说,支持ECDHE和SPDY正好是矛盾的。对于Nginx来说两者都能支持,不过因为SPDY模块不是Google在维护,所以开发进度较慢,目前的版本为2,已经不支持Chrome32和Firefox27了(感叹一下,发展太快了跟不上啊!)

Apache MPM

通常对于一个更新不怎么频繁的WordPress网站来说,Varnish已经能拦掉80%左右的流量了,对于剩下的20%和SSL流量,则进入了我们真正的Web Server。因为WordPress原生支持的是Apache服务器,所以为了更好地稳定性和易用性,我仍然选择Apache。其实Apache已经不像我们之前想的那样笨重了。

Apache MPM (multi-processing modules) 是Apache2.0推出的一个新功能,通过多处理模块来适应各种环境。目前有三种MPM的模式可供选择。传统的prefork,主力的worker和新加的event。三种模式各有各的优势。prefork稳定兼容性高,是最老的模式。worker性能强悍,是为了应对Nginx的挑战而设。event在worker的基础上优化了对keep-alive的处理方法,进一步增大了吞吐量。具体采用什么模式,需要考虑到所运行的application,不过对于wordpress和php来说,三种模式都可以运行。如果条件允许,建议尝试最新的event模式。

如果你安装的apache2.4已经compile了event模式,可以通过命令开启event模式。

a2dismod mpm_prefork
a2dismod mpm_worker
a2enmod mpm_event
service apache2 restart

验证开启了哪一个模块,可以运行

apache2ctl -V

来查看。

PHP模块还是PHP进程

如果在Apache MPM模式中选择了worker或event,则无法使用mod_php,mod_php是Apache集成的PHP处理模块,是默认用来处理php的方式。不过由于worker和event是多线程的,也就是说同一个apache2的进程里会同时处理多个不同的请求,而mod_php是集成在每一个apache2进程当中的,它无法分辨不同的线程处理的请求,也就是通常说的non thread safe。因此mod_php无法同worder和event模式并用。

解决的方法是将PHP处理从Apache中独立出来,让Apache仅处理静态文件和http请求,而将PHP的处理分发给专门从事PHP处理的进程。

说到这里,就要涉及到一系列的概念了,比如php-cgi,fastcgi,cgi,mod_fcgid,mod_fastcgi,php5-fpm,大家可以看一看这篇回答,这是我看到最清晰的解答之一。如果头痛不想看,那么结论就是对于WordPress来说,用php5-fpm处理PHP请求,并通过fastcgi协议同Apache2来传递信息,是最有效的方法,既能支持Apache的worker和event模式,也支持共享缓存,也就能更好地支持APC等Opcode缓存。

php5-fpm的安装不难,一般会认为php5-fpm和Nginx搭配比较好,其实Apache一样可以搭配。而且毫不逊色。安装同LEMP stack里一样,直接apt-get install php5-fpm就行了。

以下是Alex Sky的配置文件,放在/etc/apache2/conf-available/php5-fpm.conf,仅供参考。

<IfModule mod_fastcgi.c>
    FastCgiExternalServer %absolute_path%/php5.fcgi -socket /tmp/php5-fpm.sock -pass-header Authorization
    AddHandler application/x-httpd-fastphp5 .php
    Action application/x-httpd-fastphp5 /php5.fcgi
    Alias /php5.fcgi %absolute_path%/php5.fcgi
</IfModule>

注意更改%变量%。

%absolute_path%为网站根目录在服务器的绝对路径,比如/var/www。

在/etc/php5/fpm/pool.d/www.conf文件里面配置监听的socket。

listen = /tmp/php5-fpm.sock

之后执行service php5-fpm restart重启完成配置。

Opcode缓存

现在请求终于到达了PHP层。正常情况下,php5-fpm会读取相应的php文件,然后根据php语法解释代码,生成Opcode,再开始执行。但是我们可以缓存编译后的Opcode,之后再执行的时候不需要重新读取文件进行解释,直接从缓存的Opcode开始执行,这样大大缩短了执行时间。

负责Opcode缓存的组件是APC,全称Alternative PHP Cache。安装教程见此。配置文件建议和其他配置一起放在/etc/php5/conf.d/apc.ini。

对于WordPress的博客来说,设置64MB的cache size就足够了,以下是Alex Sky的apc.ini文件内容。

extension=apc.so
apc.shm_segments=1
apc.shm_size = 64M
apc.ttl=7200
apc.use_request_time=1
apc.user_ttl=7200
apc.gc_ttl=3600
apc.cache_by_default=1
apc.filters
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.file_update_protection=2
apc.enable_cli=0
apc.max_file_size=2M
apc.stat=1
apc.stat_ctime=0
apc.canonicalize=1
apc.write_lock=1
apc.report_autofilter=0
apc.rfc1867=0
apc.rfc1867_prefix =upload_
apc.rfc1867_name=APC_UPLOAD_PROGRESS
apc.rfc1867_freq=0
apc.rfc1867_ttl=3600
apc.include_once_override=0
apc.lazy_classes=0
apc.lazy_functions=0
apc.coredump_unmap=0
apc.file_md5=0
apc.preload_path

如果要禁用apc,就把第一行用;符号注释掉就行了。注意,不要在不同的配置文件中多次启用apc,这样会导致php的警告信息。

安装好以后可以从/usr/share/php/目录中拷贝apc.php探针到自己的网站中,可以看到实时的apc统计数据。对于WordPress来说,Opcode缓存命中率高达99.7%,也就是说php5-fpm再也不用重新解释php文件了。当然只要你重启php5-fpm,缓存就会消失并重建,所以不用担心更改application code之后缓存不同步的问题。

对于PHP5.5,Zend Optimizer成为官方的Opcode Cache,默认已经开启,所以不需要特别设置。

WordPress全页缓存

PHP开始执行代码后,就要生成html网页了。(2013.12.16更新:此处理解有误,WordPress全页缓存实际上不需要执行PHP代码,而是在Web Server层面进行Rewrite。)等等!我们为什么还要生成html?这种实时计算的东西最麻烦了,麦当劳从来不会在客人点单之后再去捕鱼杀鸡磨面,而是先把汉堡包做好,客人即点即卖,这就是WordPress全页缓存的原理。其实缓存类型和Varnish差不多,不过这次是针对Varnish漏掉的页面,并且不包括静态资源。WordPress全页缓存的插件有很多,我之前的日志推荐的Batcache,就是建立在Memcached基础上的全内存全页缓存。不过有测试表明,全内存全页缓存,其实并没有比基于硬盘的全页缓存效率高,因为Linux在系统层面会把常用的文件缓存到内存中,而Linux的内存管理效率要高过PHP,所以使用硬盘缓存效率更高。

对于WordPress全页缓存,我推荐W3 Total Cache插件。它不仅能做到全页缓存,还能进行缓存预热,也就是在还没人访问前先把缓存建好,这样所有人都能访问到缓存过的页面了。在这种情况下,全页缓存的命中率几乎是100%,除了用户即兴的搜索无法缓存,其他的页面都能缓存。W3 Total Cache还能进行自动minify,从而部分实现第一篇文章中说的前端优化。后面提到的对象缓存和数据库查询缓存,也可以通过W3 Total Cache调配,因此可以说,W3 Total Cache是WordPress在应用层面的性能管理中心。W3 Total Cache安装介绍太多了,自己百度Google之即可。

WordPress对象缓存

有些时候我们作为管理员登陆了博客,这时候全页缓存失效,全靠执行PHP代码生成HTML,因此我们到了这一步还需要继续优化。下一个被优化的就是WordPress对象缓存。作为基于对象的语言,php运行时需要存取许多数据。WordPress对象缓存就是为了缓存这一类数据。对象缓存有两种实现形式,硬盘和内存。同全页缓存不同的是,这一次我们需要用到内存缓存,因为对象缓存的存取特别频繁,如果用硬盘的话很可能会造成碎片化,降低硬盘性能,而内存就是为碎片化准备的。至于内存缓存方面,我们本可以用APC,但是APC处理碎片化并不出色,而且会导致cache full reset。于是我们采用memcached来专门进行对象缓存(以及后文马上提到的数据库查询缓存)。

安装memcached也十分简单,参见教程。在设置文件/etc/php5/conf.d/memcache.ini中uncomment extension=memcache.so开启,然后在W3 Total Cache中的对象缓存里选择memcached作为存储方式。

数据库查询缓存

有时候WordPress运行的数据在对象缓存中找不到,就会用sql来查询MySQL数据库。为了尽量减少数据库查询,我们还有最后两层缓存。

1. WordPress数据库查询缓存

这个是基于WordPress层面的,将select等语句返回的结果缓存下来,可以用W3 Total Cache调用memcached来实现。

2. MySQL Query Cache

这个是MySQL自带的,在数据库层面缓存经常执行的sql语句的返回结果。这个缓存MySQL是默认启用的,可以在/etc/mysql/my.cnf配置文件中调整缓存大小和数目,不过一般情况下不需要调整。

到此为止,我们已经将WordPress所在的服务器进行全面的优化。让我们再来看看改进后的请求处理流程吧。

  1. 用户浏览器准备发送请求
  2. 系统从DNS缓存中解析出服务器IP
  3. 如DNS缓存中没有,则通过DNS请求向上级DNS服务器逐步请求,直至获得IP(可选)(DNS缓存优化直接获得IP
  4. 浏览器同服务器建立连接(通过keep-alive保持连接
  5. 如果是SSL连接,则浏览器同服务器进行SSL Handshake(可选)(通过ECDHE和SPDY加速
  6. 浏览器向服务器发送请求(80%被Varnish拦下,从内存直接返回结果,跳过后面所有步骤
  7. 服务器的Web Server(如Apache, Nginx)收到请求,判断是否为动态请求(mpm-event模式加速处理
  8. 如果是静态请求,从硬盘中读取相应文件,返回给浏览器(命中Wordpress全页缓存,命中率90%,跳过后面所有步骤
  9. 如果是动态请求,将该请求交由PHP模块或独立PHP进程处理(php5-fpm更高效地执行
  10. PHP程序收到处理请求,从硬盘中读取相应的PHP文件(已被APC进行Opcode缓存,跳过
  11. PHP程序将PHP文件从源码编译为Opcode(已被APC进行Opcode缓存,跳过
  12. PHP程序执行Opcode(如需执行,所需数据由Memcached WordPress对象缓存提供
  13. 如果需要DB操作,则PHP程序向MySQL Server发出查询请求(可选)(Memcached WordPress数据库查询缓存,跳过
  14. MySQL Server从硬盘中读取数据库,进行查询,返回结果(可选)(MySQL Query Cache,跳过
  15. PHP将生成的HTML返回给Web Server
  16. Web Server将HTML返回给用户浏览器
  17. 用户浏览器解析HTML,展示页面,同时准备下一个请求

最后要强调的是,以上所说的各种优化方式,并不适用于所有环境,请使用前详细了解,作出最适合自己网站的决定。

2013年12月9日更新:

Alex Sky近期又进行了较大幅度的调整。目前已经从Apache转到Nginx,得益于Nginx出色的静态文件处理和W3 Total Cache的Disk Enhanced Cache,网站即使不需要Varnish也能保持很短的响应时间,反而减少了资源消耗。

之前在SSL的性能中有一点没有提到,那就是OCSP Stapling,这个对于SSL的连接有很强的提升,据说能减少响应时间30%,原理是减少浏览器进行证书验证的请求。参照这篇文章开启。

8 comments

  1. 文章写得很好,条理清晰,文字流畅,专业技术讲的深入浅出,对本人很有帮助,谢谢。
    希望有时间能再写篇文章讲讲您现在的Nginx方案的架构和具体配置。
    另外问一下您现在digital ocean的服务器架设在哪个区域?如果用wordpress搭建面向全球用户的网站,使用一台服务器是否够用呢?有必要在不同的地区租用VPS构建前置代理之类吗?

    1. 十分感谢关注。Nginx我现在的配置不是很复杂,基本按照现有网上的方案来做,只是自己加了一些应答头,实现Content-Security-Policy,这个在我后一篇文章里写到了。我的DigitalOcean现在在SFO机房,我之前是在NYC2,不过感觉内地访问稍微慢一些,所以改成SFO。全球用户的问题,我之前也考虑过,比较简单的方法是用一个CDN来分发内容,所以源头一台服务器就够用了。不过国外的某些CDN国内无法访问,所以最后折腾了半天,还是决定不用CDN。如果服务器放在北美的话,国内访问延迟大概在200ms左右,如果前端优化得比较好还是很快的。如果美国访问就秒开,欧洲访问大概在100ms内,日本香港台湾等大概150ms,印度可能会超过500ms。总的来说延时还算满意。你可以去http://www.webpagetest.org测试你的网站,看看各地真实访问情况如何。

      1. 谢谢回复!
        还想向您请教个问题:我目前的wordpress站点用了不少的第三方插件,很多插件都在wp_head中加入自己的js和css,这对于前端的加载速度非常不利,请问有什么好的原则可以用于提高wp_head的效率?
        另外,我的主题和插件用到了一些google提供的api(例如网络字体和地图),由于“网络闭关锁国(官方好像叫网络长城)”的影响这会导致国内用户访问速度极慢,请问对于这类情况您有没有好的建议?

        1. 关于前端性能,可以参考我的前一篇文章《WordPress建站心得(一)前端性能优化》。总的来说,js的数量要尽量少,加载要尽量延迟。只要对页面展示没有影响的,一律异步加载,代码可以参考Google Analytics里面的那段。如果你的插件更新不太频繁,可以将js提取,然后用Google Closure Compiler合并成一个common.js,或者两个,一个随页面加载,一个异步加载。国外的公共库我都很少用,其实展示一个页面,涉及到的域名越少越好。所以jquery等我都是直接调用自己服务器上面的版本。字体等其他元素也是如此,能放在本地的就放在本地。

    1. 直接用系统现有字体替换,去除这类请求。不过如果你觉得特别好,可以下载下来放到本地调用。一般来说连接的域名能少则少。

    1. open_file_cache是缓存文件metadata的,小流量的网站几乎没啥用。proxy_cache是只有将nginx作为最前端的reverse proxy的时候才会用到,如果直接采用nginx + php 这种结构也用不上。Linux会自动缓存经常读取的文件,所以如果大流量的话,nginx是直接读取内存缓存的,不存在性能瓶颈。

Comments are closed.