Выжимаем из WordPress максимум: nginx, php-fpm, w3c и cd

Сегодня мы попробуем выжать из популярного движка WordPress все соки. А для этого нам потребуются:

  • Быстрый вебсервер nginx
  • php в режиме fastcgi (fpm)
  • Плагин кеширования w3c
  • Какой-то CDN-сервис (опционально)
Кеширование выйдет трехуровневое: cdn, кеш w3, кеш nginx. Таким образом, фактически мы сохраняем только новые данные в базу через HTTP POST-запросы, а отдаем максимально кешированные страницы. Это особо полезно в тех случаях, когда на движке WordPress у вас популярный новостной сайт, куда переодически приходит масса посетителей. Главное — дать им возможность читать сайт, пускай ценой временного перевода авторизованных пользователей в анонимные. Последнее реализуется отдачей сохраненной страницы из кеша залогиненному пользователю, если его динамическая страница не была сгенерирована сервером из-за высокой нагрузки. Приступим:

Настройка php-fpm заключается в прописывании пути к unix-сокету и выставлению разумного числа дочерних процессов, кратное потока mysql. Например если вы указали для mysql 4 потока на процессор, то и число дочерних процессов надо выставить из расчета CPU * 4.
Плагин w3c помимо кеширования предоставляет еще возможность сохранять медиа-библиотеку на CDN-сервисе. Это очень полезно, напормер, если у вас множество фотографий. В таком случае все картинки загружаются на удаленный сервер, а их адреса заменяются на URL вида img.mydomain.com, где img указывает на CDN, который и отдае файлы вместо нас.
Ну а теперь самое главное, конфигурация nginx:
    server {

    listen 80;

    index index.php;

    #set $do_not_cache 1; #Если раскомментировать эту строку, nginx перестанет кешировать все страницы для анонимных пользователей

    server_name mydomain.com www.mydomain.com;

    root /var/www/html;

    gzip                on;

    gzip_disable        "msie6";

    gzip_vary           on;

    gzip_proxied        any;

    gzip_comp_level     5;

    gzip_buffers        16 8k;

    gzip_http_version   1.0;

    gzip_types          text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript image/png image/gif image/jpeg;

    # Обработка CSS и JS

    location ~* \.(css|js) {

        if (!-f $request_filename) {

            rewrite ^/wp-content/w3tc/min/(.+\.(css|js))$ /wp-content/w3tc/min/index.php?file=$1 last;

        }

    }

    # Сохраним url запрошенной страницы

    set $cache_uri $request_uri;

    # POST запросы не кешируются

    if ($request_method = POST) {

        set $cache_uri 'no cache';

        set $do_not_cache 1;

    }

    # Динамические страницы не кешируются

    if ($query_string != "") {

        set $cache_uri 'no cache';

        set $do_not_cache 1;

    }

    # Не кешируем админку, rpc, коментарии и тд.

    if ($request_uri ~* "(\/wp-admin\/|\/xmlrpc.php|\/wp-(app|cron|login|register|mail)\.php|wp-.*\.php|index\.php|wp\-comments\-popup\.php|wp\-links\-opml\.php|wp\-locations\.php)") {

        set $cache_uri "no cache";

        set $do_not_cache 1;

    }

    # Не кешируем зарегистрированных пользователей

    if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp\-postpass|wordpress_logged_in") {

        set $cache_uri 'no cache';

        set $do_not_cache 1;

    }

    # Если страница не закеширована w3c, то отдаемся на милость WordPress

    location / {

        try_files /wp-content/w3tc/pgcache/$cache_uri/_index.html $uri $uri/ /index.php?q=$uri&$args;

    }

    # Статичный контент отдаем напрямую с диска

    location ~* \.(xml|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {

        try_files       $uri =404;

        access_log      off;

        expires         7d;

    }

    # Запрещаем доступы к .ht - файлам

    location ~* /\.ht {

        deny            all;

        access_log      off;

        log_not_found   off;

    }

#И наконец самое главное - обработка PHP
location ~ \.php$ {

            fastcgi_buffers 8 256k;

            fastcgi_buffer_size 128k;

            fastcgi_intercept_errors on;

            include fastcgi.conf;

            fastcgi_pass unix:/dev/shm/php-fpm-www.sock;

            fastcgi_ignore_headers Set-Cookie Cache-Control Expires;

            fastcgi_no_cache $do_not_cache;

            fastcgi_cache_bypass $do_not_cache;

            fastcgi_cache staticfilecache;

            fastcgi_cache_valid 200 20m;

            fastcgi_cache_key "$server_addr:$server_port$request_uri";

            fastcgi_cache_use_stale updating error timeout invalid_header http_500;

        }

}