問題描述

您推薦什麼緩存插件配置,以及為什麼在以下假設下:

  • 完全控制服務器配置

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