Кеш: кеширование WordPress сайта с помощью nginx
Почему уже почти неделю мне на дает покоя вопрос ускорения CosyDale.com (а также всех других сайтов на сервере). Причина – просто желание и возможно необходимость в будущем разместить крутой проект.
Пару дней назад я ковырялся с кешированием с помощью XCache. Это помогло значительно снизить нагрузку от выполнения php скриптов. До этого я облегчил главную страницу, внедрив частичное кеширование результатов запроса к мускулу (кстати, спасибо Юрию Белотицкому за подсказку про memcache, но все руки не доходят). И вот вчера я задумался о глобальном кешировании на стороне самого nginx.
У меня уже стояла отдача контента в gzip, также принудительное запихивание графики, стилей и скриптов в кеш браузера. Теперь благодаря статье Владимира – WordPress: кэширование средствами nginx – я смог значительно ускорить свой сайт.
Стартовые условия: выделенные лично под меня 2Ггц проца, 2 Гб оперативной памяти, FreeBSD 8, nginx, XCache, отсутствие WordPress плагинов кеширования, наличие своего частичного кеширования.
Результат представлен ниже:
Проводилось тестирование утилитой ab : 10000 запросов в 100 потоков.
Чтобы запустить кеширование от nginx, описанное в статье у Владимира, мне надо было обновить сам nginx (у меня стояла версия 0.7.67, в которой нет поддержки параметров fastcgi_cache_bypass и других – все это появилось в 0.8.64). Итак, порядок команд, которые прописывал в терминале (работу с портами читаем тут) – постараюсь ничего не упустить:
# мне надо было обновить порты (впервые за 9 месяцев) - долго... portsnap fetch update # ставим portupgrade, чтобы в будущем не было проблем с обновлением cd /usr/ports/ports-mgmt/portupgrade/ && make install clean # если он у вас уже есть, то вам об это скажут, тогда вам надо будет удалить его cd /usr/ports/ports-mgmt/portupgrade/ && make deinstall clean # и заново поставить - новую версию cd /usr/ports/ports-mgmt/portupgrade/ && make install clean # сбрасываем хеш rehash # запускаем обновление базы портов - долго... portsdb -Uu # теперь обновляем сам nginx до последней версии из портов - долго... portupgrade -R nginx # все.
Теперь приступим к настройке. Я вставлю сюда пример рабочего конфига:
user www www; # везде советуют 2 или по количеству процов, если у вас больше процессоров worker_processes 2; error_log logs/error.log; pid /var/run/nginx.pid; events { # умножим worker_connections на worker_processes и получаем максимум пользователей ежемоментно, которые могут получить доступ к сайту worker_connections 256; use kqueue; } http { include mime.types; default_type application/octet-stream; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 48s; client_max_body_size 4m; # сжимаем контент перед отдачей, если он больше 1024 байт, с рейтом 5, но не для IE6 и ранее - не поддерживают gzip on; gzip_disable "MSIE [1-6]\.(?!.*SV1)"; gzip_min_length 1024; gzip_comp_level 5; gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript; # Непостредственно правила для домена example.com # Папка /tmp/nginx/example должна уже существовать! fastcgi_cache_path /tmp/nginx/example levels=2 keys_zone=example:10m max_size=512m inactive=20m; server { listen 80; server_name example.com; root /usr/local/www/example.com/www; index index.php; charset utf8; # объявляем о необходимости кешировать только тех, у кого НЕТ куки комментатора (боты и большинство других посетителей) if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" ) { set $do_not_cache 1; } fastcgi_cache_bypass $do_not_cache; fastcgi_no_cache $do_not_cache; fastcgi_pass_header Cookie; fastcgi_cache example; fastcgi_cache_key $request_method|$host|$request_uri; fastcgi_cache_valid 301 8h; fastcgi_cache_valid 404 1h; # важно: это время жизни кеша страницы - больше значение, реже обновляется, но и меньше нагрузки fastcgi_cache_valid 200 1h; include /usr/local/etc/nginx/ext-antilich.conf; include /usr/local/etc/nginx/ext-setlimit.conf; access_log /usr/local/www/example.com/_logs/access.log; error_log /usr/local/www/example.com/_logs/error.log; error_page 404 /404.html; location = /404.html { root /usr/local/www/example.com/_errors; } # redirect server error pages to the static page /50x.html error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/local/www/example.com/_errors; } # не кешируем админку и некоторые другие страницы location ~ ^/(wp-admin/.*\.php|wp-login\.php|wp-register\.php)$ { try_files $uri @wordpress; set $do_not_cache 1; fastcgi_cache_bypass 1; fastcgi_no_cache 1; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include /usr/local/etc/nginx/fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } # обычная обработка php скриптов location ~* \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /usr/local/www/example.com/www$fastcgi_script_name; include /usr/local/etc/nginx/fastcgi_params; fastcgi_intercept_errors off; fastcgi_pass_header Set-Cookie; } # основное правило для работы WordPress location / { root /usr/local/www/example.com/www; index index.php index.html; if (!-e $request_filename) { rewrite ^.*$ /index.php last; } } # а ниже мы запихиваем эти файлы в кеш браузера насильственно # добавлем Expiration Date +99 дней с момента первого обращения браузера к ним location ~* ^.+\.(css|js|png|jpg|gif|jpeg|ico)$ { access_log off; expires 99d; } } }
Не забудьте example.com сменить на ваш домен, example – на ваш идентификатор, а также поменять (если надо) пути к соответствующим папкам в вашей системе.
После внесения изменений в nginx.conf – перезапустите его:
/usr/local/etc/rc.d/nginx restart
После этого все должно начать летать :)
Есть 1 минус – не работает каптча :(
Каптча вроде работает.. если SI Captcha…
Насчет летает – да :) единственно но – нужно аккуратно смотреть что кладется в кеш.. иногда кеш это зло)
Владимир молодец – видел твой коммент и его ответ у него.
Согласен по поводу “зло” иногда.
Я думаю уменьшить время кеша тут на сайте и сделать его для всех – и для меня в том числе, тогда скорость будет отличнейшая и для авторизованных. Вот только не уверен, как будет работать добавление комментариев – получается, что после комментирования будет отдаваться кеш страницы, где его еще нет…
кеш для зарегиных – это такой вагон глюков.. мрак! убрал везде где только возможно!
Сейчас зайду к нему на сайт…
Ну тут на CD.com зарегистрированный только я… Но в общем и целом ты прав.
Надо создавать кеш для каждого конкретного пользователя – а это капец винту и скорости отдачи контента при большом количестве пользователей.
проблема при кешировании (основная) – что контент отдавался без привязки к юзеру и юзерА мог спокойно видеть то что должен видеть только юзерБ.. получается каша.. и даже правила которые создает для nginx w3total – никак не помогают…
По ходу, эта статья оказалась слишком гикнутой для посетителей сайта :(
В ведь такое классное решение… И ведь его можно настроить дополнительно.
break в секции статики! location для статики – в самое начало!
На чем основано? Я смотрел видео Сысоева, он говорил, что без разницы.
ставил limit_req… без break; – ухожу за 200.. если break; – то и 50 не получается)))))
так что может он и говорил… но без break – смысла в защите по кол-ву запросов – нет ;)
а что такое “гикнутая”?..
Я имел в виду, что это не решение, которое 1 раз легко установил (как плагин Reveal ID, к примеру) и забыл. Для более продвинутых, так сказать…
да все нужно постоянно оптимизировать.. условия работы то меняются.. постоянно!
Читал недавно книги Н.Мациевского speedupyourwebsite.ru/ – если еще не знакомы, то советую. Книги содержат очень интересныве практические советы по клиентской и немного серверной оптимизации (также и в части nginx).
Кстати, по поводу директивы fastcgi_pass 127.0.0.1:9000 есть мнение. Это несколько быстрее работает при использовании unix socket. У меня в паре с nginx крутится php-fpm, так вот я делаю так:
1) в конфиге сервера nginx:
location ~ .php$ {
fastcgi_pass unix:/var/run/www-php-pool;
fastcgi_index index.php;
fastcgi_intercept_errors on;
include /etc/nginx/fastcgi_params;
fastcgi_read_timeout 300;
fastcgi_send_timeout 300;
fastcgi_buffers 256 16k;
fastcgi_buffer_size 32k;
include fastcgi_params;
}
2) соответственно, в настройках пула php-fpm:
listen = /var/run/www-php-pool
Мелочь, а приятно.
Немного не в тему но у меня такой вопрос установил я nginx php msql + phpadmin для управления базами данных настроил кэширование, но при установке плагина через меню wp у меня запрашивает логин и пароль от ftp сервера, соответственно ftp сервер я не ставил он мне не нужен, хорошо, и это небольшая проблема, загрузил я плагины через sftp с помощью fileZilla, работают но не все, те плагины которым нужно создать папки для кэша, или еще для чего создать их не могут у них на это нет прав, так вот как решить данную проблему подскажите если кто нибудь в курсе, раньше делал но забыл как давно было?