问题描述

您推荐什么缓存插件配置,以及为什么在以下假设下:

  • 完全控制服务器配置

  • 在 multi-site /multi-domain 模式下运行 WordPress

  • 大多数域名不使用 www. 前缀 (cookies)

  • (愿望) 能够对特定 IP 或基于 cookie 禁用缓存,当您对不需要缓存的站点进行更改时。

详细信息:我正在使用 Firefox Google Page Speed 插件来尝试优化网站的速度。

另外请不要引用通用指南,比如较小的图像。

让我们公平起来,使用多个缓存插件会为您带来比解决问题更多的问题,所以请尝试给出一个简单的方法。

最佳解决方案

“what plugin” 的基本答案可能是 W3 Total Cache 。它是当时功能最强大的插件之一。然而,完整的性能链是 WordPress 插件可以处理的时间要长得多。

  1. Web 服务器 (Apache 或其他) 配置 (响应时间,到第一个字节的时间,头) 。

  2. 数据库 (花费处理查询的时间) 。

  3. PHP /WordPress(页面生成时间,内存消耗) 。

  4. Front-end 性能 (HTTP 请求量,带宽) 。

良好的开始将是静态缓存插件 (如 W3) 与操作码 memory-based 缓存如 APC

但是,从内存分发网络,备用 Web 服务器等方面来看,还有更多 (和更复杂) 的方式可以做的事情。

次佳解决方案

我的 WordPress 性能和缓存堆栈

这是针对中低档单服务器或 VPS 的最佳 WordPress 性能堆栈。我正在将中档区分为单核,大约有 1G 的内存和相当快的驱动器。

服务器堆栈

  • Linux – Debian Lenny 或 Ubuntu

  • Nginx – 配置为反向代理静态文件缓存

  • Apache – Apache 将处理由 Nginx 在另一个端口上卸载的 PHP

  • MySql – 由 WP 要求,请确保运行最新的稳定版本

  • PHP – 最新稳定版本的 5.2 或 5.3 分支

PHP 缓存

  • APC – 配置 mmap 内存和 shm 大小至少 128M

WordPress 性能插件堆栈

  • Nginx proxy cache integrator

  • W3 Total Cache – 将页面缓存设置为磁盘增强,缩小到磁盘,将对象和数据库设置为 APC 。

    • 自主 CDN – 创建 4 个 cname 别名,指向服务器上设置的仅用于提供静态文件的域

使用 W3 Total Cache,我们使用磁盘进行页面缓存和 minify,因为 Nginx 将非常快速地为我们的静态文件提供服务。

如何配置 Nginx 来提供静态文件并将 PHP 传递给 Apache

单独使用 Apache 的问题是,即使对于静态文件,它也会打开一个连接,并在每个请求上都打到 php 。这会浪费连接,因为 Apache 会保持打开状态,并且当您有很多流量时,即使没有使用连接,您的连接也会陷入死锁。

默认情况下,Apache 监听端口 80 上的请求,这是默认的 Web 端口。首先,我们将对我们的 Apache conf 和虚拟主机文件进行更改,以侦听端口 8080 。

Apache 配置

httpd.conf 文件

将 KeepAlive 设置为关闭

ports.conf

NameVirtualHost *:8080
Listen 8080

每站虚拟主机

<VirtualHost 127.0.0.1:8080>
     ServerAdmin info@yoursite.com
     ServerName yoursite.com
     ServerAlias www.yoursite.com
     DocumentRoot /srv/www/yoursite.com/public_html/
     ErrorLog /srv/www/yoursite.com/logs/error.log
     CustomLog /srv/www/yoursite.com/logs/access.log combined
</VirtualHost>

您还应该安装 mod_rpaf,以便您的日志将包含访问者的真实 IP 地址。如果您的日志不是 127.0.0.1 作为始发 IP 地址。

Nginx 配置

在 Debian 上,您可以使用存储库进行安装,但它们只包含版本 0.6.33 。要安装更高版本,您必须添加 lenny backports 包

$ nano /etc/apt/sources.list

将此行添加到文件 deb http://www.backports.org/debian lenny-backports main

$ nano /etc/apt/preferences

将以下内容添加到文件中:

Package: nginx
Pin: release a=lenny-backports
Pin-Priority: 999

发出以下命令从 backports.org 导入密钥以验证软件包并更新系统的软件包数据库:

$ wget -O - http://backports.org/debian/archive.key | apt-key add -
$ apt-get update

现在安装 apt-get

apt-get install nginx

这比编译源码容易得多。

Nginx conf 和服务器文件配置

nginx.conf

user www-data;
worker_processes  4;

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    access_log  /var/log/nginx/access.log;
    client_body_temp_path /var/lib/nginx/body 1 2;
    gzip_buffers 32 8k;
    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;
    tcp_nodelay        on;

    gzip  on;

  gzip_comp_level   6;
  gzip_http_version 1.0;
  gzip_min_length   0;
  gzip_types        text/html text/css image/x-icon
        application/x-javascript application/javascript text/javascript application/atom+xml application/xml ;



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

现在您将需要设置您的 Nginx 虚拟主机。我喜欢使用 sites-enabled 方法,每个 v 主机 sym 链接到 sites-available 目录中的一个文件。

$ mkdir /etc/nginx/sites-available
$ mkdir /etc/nginx/sites-enabled
$ touch /etc/nginx/sites-available/yourservername.conf
$ touch /etc/nginx/sites-available/default.conf
$ ln -s  /etc/nginx/sites-available /etc/nginx/sites-enabled
$ nano /etc/nginx/sites-enabled/default.conf

default.conf

注意:

以下文件中的静态缓存设置仅在启用 Nginx 代理缓存集成器插件时有效。

proxy_cache_path  /var/lib/nginx/cache  levels=1:2   keys_zone=staticfilecache:180m  max_size=500m;
proxy_temp_path /var/lib/nginx/proxy;
proxy_connect_timeout 30;
proxy_read_timeout 120;
proxy_send_timeout 120;

#IMPORTANT - this sets the basic cache key that's used in the static file cache.
proxy_cache_key "$scheme://$host$request_uri";

upstream wordpressapache {
        #The upstream apache server. You can have many of these and weight them accordingly,
        #allowing nginx to function as a caching load balancer
        server 127.0.0.1:8080 weight=1 fail_timeout=120s;
}

每 WordPress 网站 conf(对于多站点,您只需要一个虚拟主机)

server {
        #Only cache 200 responses, and for a default of 20 minutes.
        proxy_cache_valid 200 20m;

        #Listen to your public IP
        listen 80;

        #Probably not needed, as the proxy will pass back the host in "proxy_set_header"
        server_name www.yoursite.com yoursite.com;
        access_log /var/log/nginx/yoursite.proxied.log;

        # "combined" matches apache's concept of "combined". Neat.
        access_log  /var/log/apache2/nginx-access.log combined;
        # Set the real IP.
        proxy_set_header X-Real-IP  $remote_addr;

        # Set the hostname
        proxy_set_header Host $host;

        #Set the forwarded-for header.
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        location / {
                        # If logged in, don't cache.
                        if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" ) {
                                set $do_not_cache 1;
                        }
                        proxy_cache_key "$scheme://$host$request_uri $do_not_cache";
                        proxy_cache staticfilecache;
                        proxy_pass http://wordpressapache;
        }

        location ~* wp-.*.php|wp-admin {
                        # Don't static file cache admin-looking things.
                        proxy_pass http://wordpressapache;
        }

        location ~* .(jpg|png|gif|jpeg|css|js|mp3|wav|swf|mov|doc|pdf|xls|ppt|docx|pptx|xlsx)$ {
                        # Cache static-looking files for 120 minutes, setting a 10 day expiry time in the HTTP header,
                        # whether logged in or not (may be too heavy-handed).
                        proxy_cache_valid 200 120m;
                        expires 864000;
                        proxy_pass http://wordpressapache;
                        proxy_cache staticfilecache;
        }

        location ~* /[^/]+/(feed|.xml)/? {
 # Cache RSS looking feeds for 45 minutes unless logged in.
                        if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" ) {
                                set $do_not_cache 1;
                        }
                        proxy_cache_key "$scheme://$host$request_uri $do_not_cache";
                        proxy_cache_valid 200 45m;
                        proxy_cache staticfilecache;
                        proxy_pass http://wordpressapache;
        }

        location = /50x.html {
                root   /var/www/nginx-default;
        }

        # No access to .htaccess files.
        location ~ /.ht {
                deny  all;
        }

        }

自主 CDN 配对

对于您自己托管的 CDN conf,只需要设置它来提供静态文件,而不需要代理通过

server {

        proxy_cache_valid 200 20m;
        listen 80;
        server_name yourcdndomain.com;
        access_log   /srv/www/yourcdndomain.com/logs/access.log;
        root   /srv/www/yourcdndomain.com/public_html/;

 proxy_set_header X-Real-IP  $remote_addr;

      location ~* .(jpg|png|gif|jpeg|css|js|mp3|wav|swf|mov|doc|pdf|xls|ppt|docx|pptx|xlsx)$ {
                                # Cache static-looking files for 120 minutes, setting a 10 day expiry time in the HTTP header,
                                # whether logged in or not (may be too heavy-handed).

                                proxy_cache_valid 200 120m;
                        expires 7776000;
                        proxy_cache staticfilecache;
                }

location = /50x.html {
                root   /var/www/nginx-default;
        }

 # No access to .htaccess files.
        location ~ /.ht {
          deny  all;
        }

    }

现在启动服务器

$ /etc/init.d/apache2 restart
$/etc/init.d/nginx start

基准测试结果

在 Apache Bench 上,这个设置理论上可以每秒服务 1833.56 个请求

$ ab -n 1000 -c 20 http://yoursite.com/

第三种解决方案

使用最少 64MB Ram 的网站空间用于 Multisite,并在 Apache 上使用 APC 和 Memcached,缓存不是静态的,您可以毫无问题地使用所有 WP-functions 。您通过 PageSpeed 扫描还读取其他选项,在主题中编码。缓存可以做一个伟大的工作,但不能修复坏的主题或插件。另一个解决方案是在 WordPress 中使用没有 Cookie 的子域名作为 CDN 。将其添加到 wp-config.php,仅在域上,而不是子域。

define( 'COOKIE_DOMAIN', 'example.com' );

现在在主题的 functions.php 中设置新的函数,或者编写一个插件来将静态内容的路径替换到你的子域,你的自定义 CDN 。

// replace for CDN on bloginfo
if ( !function_exists('fb_add_static_wpurl') ) {
    function fb_add_static_wpurl($info, $show) {

        if ( is_admin() )
            return $info;

        $keys = array(
            'url',
            'wpurl',
            'stylesheet_url',
            'stylesheet_directory',
            'template_url',
            'template_directory',
            );

        if ( in_array( $show, $keys ) ) {

            $wpurl = get_bloginfo('wpurl');

            $search = array(
                $wpurl . '/wp-content/images/',
                $wpurl . '/wp-content/download/',
                $wpurl . '/wp-content/themes/',
                $wpurl . '/wp-content/plugins/',
            );

            $replace = array(
                'http://cdn1.example.com/',
                'http://cdn2.example.com/',
                'http://cdn3.example.com/',
                'http://cdn4.example.com/',
            );

            return str_replace( $search, $replace, $info );

        } else {
            return $info;
        }
    }
    add_filter( 'bloginfo_url', 'fb_add_static_wpurl', 9999, 2 );
}

现在的模板和 stylesheet-path 的功能

function fb_add_static_stylesheet_uri($uri) {

            if ( is_admin() )
                return $uri;

            $wpurl = get_bloginfo('wpurl');

            $search = array(
                $wpurl . '/wp-content/images/',
                $wpurl . '/wp-content/download/',
                $wpurl . '/wp-content/themes/',
                $wpurl . '/wp-content/plugins/',
            );

            $replace = array(
                'http://cdn1.example.com/',
                'http://cdn2.example.com/',
                'http://cdn3.example.com/',
                'http://cdn4.example.com/',
            );
            return str_replace( $search, $replace, $uri );

}
add_filter ( 'template_directory_uri', 'fb_add_static_stylesheet_uri' );
add_filter ( 'stylesheet_uri', 'fb_add_static_stylesheet_uri' );
add_filter ( 'stylesheet_directory_uri', 'fb_add_static_stylesheet_uri' );

现在在没有 Cookie 的前端静态 CDN 网址上阅读 「页面速度」 。

还要添加以下源代码.htaccess for block dublicate content:

##
# Explicitly send a 404 header if a file on cdn[0-9].example.org is not
# found. This will prevent the start page (empty URL) from being loaded.
##
RewriteCond %{HTTP_HOST} ^cdn[0-9].example.org [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* - [R=404,L]

##
# Do not dispatch dynamic resources via cdn[0-9].example.org.
##
RewriteCond %{HTTP_HOST} ^cdn[0-9].example.org [NC]
RewriteCond %{REQUEST_FILENAME} .(php|html)$
RewriteRule .* - [R=404,L]

请使用这个功能,也是例子,你可以用我的想法写出你的解决方案。

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。