Кеш: кеширование 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 минус – не работает каптча :(

комментариев 17

  1. Jettochkin:

    Каптча вроде работает.. если SI Captcha…

    Насчет летает – да :) единственно но – нужно аккуратно смотреть что кладется в кеш.. иногда кеш это зло)

    • Владимир молодец – видел твой коммент и его ответ у него.
      Согласен по поводу “зло” иногда.
      Я думаю уменьшить время кеша тут на сайте и сделать его для всех – и для меня в том числе, тогда скорость будет отличнейшая и для авторизованных. Вот только не уверен, как будет работать добавление комментариев – получается, что после комментирования будет отдаваться кеш страницы, где его еще нет…

      • Jettochkin:

        кеш для зарегиных – это такой вагон глюков.. мрак! убрал везде где только возможно!

        Сейчас зайду к нему на сайт…

        • Ну тут на CD.com зарегистрированный только я… Но в общем и целом ты прав.
          Надо создавать кеш для каждого конкретного пользователя – а это капец винту и скорости отдачи контента при большом количестве пользователей.

          • Jettochkin:

            проблема при кешировании (основная) – что контент отдавался без привязки к юзеру и юзерА мог спокойно видеть то что должен видеть только юзерБ.. получается каша.. и даже правила которые создает для nginx w3total – никак не помогают…

  2. По ходу, эта статья оказалась слишком гикнутой для посетителей сайта :(
    В ведь такое классное решение… И ведь его можно настроить дополнительно.

    • Jettochkin:

      break в секции статики! location для статики – в самое начало!

      • На чем основано? Я смотрел видео Сысоева, он говорил, что без разницы.

        • Jettochkin:

          ставил limit_req… без break; – ухожу за 200.. если break; – то и 50 не получается)))))

          так что может он и говорил… но без break – смысла в защите по кол-ву запросов – нет ;)

    • Jettochkin:

      а что такое “гикнутая”?..

      • Я имел в виду, что это не решение, которое 1 раз легко установил (как плагин Reveal ID, к примеру) и забыл. Для более продвинутых, так сказать…

        • Jettochkin:

          да все нужно постоянно оптимизировать.. условия работы то меняются.. постоянно!

  3. Александр:

    Читал недавно книги Н.Мациевского speedupyourwebsite.ru/ – если еще не знакомы, то советую. Книги содержат очень интересныве практические советы по клиентской и немного серверной оптимизации (также и в части nginx).

  4. stanis:

    Кстати, по поводу директивы 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

    Мелочь, а приятно.

  5. Немного не в тему но у меня такой вопрос установил я nginx php msql + phpadmin для управления базами данных настроил кэширование, но при установке плагина через меню wp у меня запрашивает логин и пароль от ftp сервера, соответственно ftp сервер я не ставил он мне не нужен, хорошо, и это небольшая проблема, загрузил я плагины через sftp с помощью fileZilla, работают но не все, те плагины которым нужно создать папки для кэша, или еще для чего создать их не могут у них на это нет прав, так вот как решить данную проблему подскажите если кто нибудь в курсе, раньше делал но забыл как давно было?

  1. 03.10.2011

    […] серьезную ошибку в настройках nginx, описанную в записи Кеш: кеширование WordPress сайта с помощью nginx. Я удалил упоминание о feed в строке location, где указываю, […]

  2. 12.10.2011

    […] кеширование на стороне веб-сервера – nginx (как это сделать); […]

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *