問題描述

您推薦什麼快取外掛配置,以及為什麼在以下假設下:

  • 完全控制伺服器配置

  • 在 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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。