Настройка Varnish для Drupal на Apache в Debian или Ubuntu

Drupal – это система управления контентом с открытым исходным кодом и платформа, написанная на PHP. Drupal используется для создания полнофункциональных сайтов и веб-приложений любого размера с бэкэндом. Drupal распространяется по GNU General Public License, что означает, что любой человек может свободно использовать это программное обеспечение, вносить свой вклад в проект и делиться им с другими.

Платформы типа Drupal отлично подходят для быстрого построения и разработки приложений. Однако так же быстро возникают различные проблемы, связанные с ростом приложения. Чтобы продолжать быстро обслуживать клиентов, сохранить интерес к приложению и оптимизировать его работу, необходимо выполнить масштабирование.

Данный мануал поможет настроить Varnish для Drupal, чтобы значительно сократить время, затрачиваемое пользователями на загрузку сайта и увеличить пропускную способность сервера, передавая запросы через программное обеспечение Varnish Cache.

Масштабирование

Существует два подхода – вертикальное и горизонтальное масштабирование.

Вертикальное масштабирование – это, по сути, увеличение ресурсов одного компьютера или сервера. Увеличение объема памяти, замена процессора более быстрым, добавление новых дисков с отличной скоростью чтения и записи можно рассматривать как вертикальное масштабирование.

Горизонтальное масштабирование – это увеличение количества серверов (за счет чего увеличивается и вычислительная мощность). К примеру, когда вы покупаете несколько недорогих серверов и объединяете их в одну систему – это и есть горизонтальное масштабирование. Это можно реализовать различными способами: запустить каждую программу стека на отдельной машине, клонировать веб-серверы для создания других пользователей, распределить входящие запросы от клиентов через обратный прокси типа NGINX.

Что такое Varnish?

Varnish Cache обслуживает статический или квазистатический контент напрямую, без передачи запроса на веб-сервер (то есть Apache). Поскольку большое количество контента необходимо вычислить и сгенерировать только один раз, сохранение и последующее обслуживание из памяти быстрого доступа значительно уменьшает нагрузку на веб-сервер и увеличивает количество запросов, которые может одновременно обрабатывать система.

Varnish может увеличить скорость (в зависимости от архитектуры) и надежность практически любого сайта. Это делает сайт более дружественным к пользователям.

: Если вы не используете отдельный экземпляр сервера приложений для Varnish (что настоятельно рекомендуется сделать), технически это не будет масштабированием, но положительно повлияет на системную архитектуру. Конечно, это можно назвать в некотором роде масштабированием, так как это увеличит общую производительность системы и нагрузку, которую может обработать сервер, в результате получается системная архитектура, которая готова к масштабированию.

1: Подготовка веб-сервера к запуску Varnish

Varnish должен быстро обслуживать страницы прямо из памяти. Этот процесс называется кэшированием. Для того, чтобы это сработало, Varnish должен обрабатывать входящие запросы. Учитывая, что веб-сервер (например, Apache) делает то же самое (обрабатывает входящие запросы), нужно внести некоторые изменения для того, чтобы Varnish смог занять его место. Для этого нужно изменить порт, который он прослушивает (т. е. порт 80).

По умолчанию Apache слушает порт 80.

Отредактируйте параметры в файле ports.conf в каталоге /etc/apache2/.

Откройте файл в редакторе:

sudo nano /etc/apache2/ports.conf

В файле содержатся примерно такие строки:

NameVirtualHost *:80
Listen 80
<IfModule mod_ssl.c>
# If you add NameVirtualHost *:443 here, you will also have to change
# the VirtualHost statement in /etc/apache2/sites-available/default-ssl
# to <VirtualHost *:443>
# Server Name Indication for SSL named virtual hosts is currently not
# supported by MSIE on Windows XP.
Listen 443
</IfModule>
<IfModule mod_gnutls.c>
Listen 443
</IfModule>

Измените первые две строки, где указан номер порта. Вместо стандартного порта 80 можно использовать, скажем, 8000 (запомните этот номер):

NameVirtualHost *:8000
Listen 8000

Сохраните и закройте файл (CTRL+X, Y и enter).

Если ваш сервер обслуживает несколько сайтов или на нем установлены индивидуальные параметры домена, у вас, вероятно, есть виртуальные хосты. Эти файлы тоже нужно обновить.

Откройте файл виртуального хоста в редакторе:

sudo nano /etc/apache2/sites-availbable/my-domain-dot-com

Примечание: Вместо my-domain-dot-com укажите имя своего сайта. Если у вас нет пользовательского виртуального хоста, откройте файл по умолчанию, /etc/apache2/sites-available/default.

В зависимости от текущих настроек вы увидите документ, который начинается так:

<VirtualHost *:80>

Здесь нужно указать новый порт:

<VirtualHost *:8000>

Сохраните и закройте файл.

Чтобы обновить настройки, перезапустите Apache:

sudo service apache2 reload

Теперь веб-сервер принимает входящие соединения по порту 8000.

2: Установка Varnish Cache

В Debian и Ubuntu пакет Varnish предоставляется стандартным менеджером пакетов apt. Однако чтоб получить последнюю версию, сайт varnish предлагает добавить URL для загрузки Varnish в список источников aptitude. Прежде нужно добавить ключ безопасности с http://repo.varnish-cache.org.

wget http://repo.varnish-cache.org/debian/GPG-key.txt
apt-key add GPG-key.txt

Добавьте URL в список источников apt-get.

# Debian:
echo "deb http://repo.varnish-cache.org/debian/ wheezy varnish-3.0" >> /etc/apt/sources.list
# Ubuntu:
echo "deb http://repo.varnish-cache.org/ubuntu/ precise varnish-3.0" | sudo tee -a /etc/apt/sources.list

Обновите менеджер пакетов, а затем загрузите и установите Varnish Cache:

apt-get update
apt-get install varnish

3: Настройка Varnish

По умолчанию Varnish не работает по порту 80, и это нужно изменить.

Конфигурационный файл в Debian и Ubuntu находится в /etc/default/varnish.

Откройте файл в редакторе:

nano /etc/default/varnish

После этого на экране вы увидите довольно длинный, но очень простой документ. Найдите блок DAEMON_OPTS, который определяет параметры демона Varnish:

DAEMON_OPTS="-a :6081 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-s malloc,256m"

Измените порт 6081 на 80:

DAEMON_OPTS="-a :80 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-s malloc,256m"

Varnish использует файл .vcl (по умолчанию он находится в /etc/varnish/), который содержит инструкции по запуску программы, написанные на языке VCL. Этот файл определяет, как Varnish будет обрабатывать запросы и как должна работать система кэширования документов. Когда загружается новый набор инструкций (через файл .vcl), Varnish преобразовывает их в код C и компилирует его, что затем используется для выполнения этой задачи.

Файлы VCL сначала могут показаться сложными, поскольку они позволяют определить большое количество задач. К счастью, сайт проекта предоставляет много полезных примеров.

Для Drupal можно использовать следующие параметры. Скопируйте и вставьте строки, представленные ниже, в файл .vcl.

nano /etc/varnish/default.vcl

Открыв файл, вы увидите длинный документ с параметрами по умолчанию.

Для начала нужно определить параметры веб-сервера и настроить его взаимодействие с Varnish. Отредактируйте раздел backend default:

backend default {
.host = "127.0.0.1";
.port = "8000";
.max_connections = 250;
.connect_timeout = 300s;
.first_byte_timeout = 300s;
.between_bytes_timeout = 300s;
}

Примечание: Ниже вы найдете большой закомментированный блок стандартного кода конфигураций VCL. Будьте внимательны, не раскомментируйте его по ошибке, иначе при компиляции возникнут ошибки.

Затем добавьте белый список адресов:

acl purge {
"localhost";
"127.0.0.1";
}

Чтобы определить адреса, которые могут получить доступ к cron.php или install.php, добавьте следующее:

acl internal {
"192.10.0.0"/24;
# For remote access, add your IP address here.
# Ex: 162.xxx.xx.xx
}

Далее нужно написать программу, которая будет управлять входящими запросами клиентов. Вставьте в файл следующий блок:

sub vcl_recv {
# A great functionality of Varnish is to check
# your web server's health and serve stale pages
# if necessary.
# In case of web server lag, let's return the
# request with stale content.
if (req.backend.healthy)
{
set req.grace = 60s;
}
else
{
set req.grace = 30m;
}
# Modify (remove) progress.js request parameters.
if (req.url ~ "^/misc/progress\.js\?[0-9]+$")
{
set req.url = "/misc/progress.js";
}
# Modify HTTP X-Forwarded-For header.
# This will replace Varnish's IP with actual client's.
remove req.http.X-Forwarded-For;
set    req.http.X-Forwarded-For = client.ip;
# Check if request is allowed to invoke cache purge.
if (req.request == "PURGE")
{
if (!client.ip ~ purge)
{
# Return Error 405 if not allowed.
error 405 "Forbidden - Not allowed.";
}
return (lookup);
}
# Verify HTTP request methods.
if (req.request != "GET"    && req.request != "HEAD" &&
req.request != "PUT"    && req.request != "POST" &&
req.request != "TRACE"  && req.request != "OPTIONS" &&
req.request != "DELETE" && req.request != "PURGE")
{
return (pipe);
}
# Handling of different encoding types.
if (req.http.Accept-Encoding)
{
if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$")
{
remove req.http.Accept-Encoding;
}
elsif (req.http.Accept-Encoding ~ "gzip")
{
set req.http.Accept-Encoding = "gzip";
}
elsif (req.http.Accept-Encoding ~ "deflate")
{
set req.http.Accept-Encoding = "deflate";
}
else
{
remove req.http.Accept-Encoding;
}
}
# Force look-up if request is a no-cache request.
if (req.http.Cache-Control ~ "no-cache")
{
return (pass);
}
# Do not allow outside access to cron.php or install.php. Depending on your access to the server, you might want to comment-out this block of code for development.
if (req.url ~ "^/(cron|install)\.php$" && !client.ip ~ internal)
{
# Throw error directly:
error 404 "Page not found.";
# Or;
# Use a custom error page on path /error-404.
# set req.url = "/error-404";
}
# Remove certain cookies.
set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "Drupal.toolbar.collapsed=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");
if (req.http.cookie ~ "^ *$")
{
unset req.http.cookie;
}
# Cache static content of themes.
if (req.url ~ "^/themes/" && req.url ~ ".(css|js|png|gif|jp(e)?g)")
{
unset req.http.cookie;
}
# Do not cache these URL paths.
if (req.url ~ "^/status\.php$" ||
req.url ~ "^/update\.php$" ||
req.url ~ "^/ooyala/ping$" ||
req.url ~ "^/admin"        ||
req.url ~ "^/admin/.*$"    ||
req.url ~ "^/user"         ||
req.url ~ "^/user/.*$"     ||
req.url ~ "^/users/.*$"    ||
req.url ~ "^/info/.*$"     ||
req.url ~ "^/flag/.*$"     ||
req.url ~ "^.*/ajax/.*$"   ||
req.url ~ "^.*/ahah/.*$")
{
return (pass);
}
# Cache the following file types.
if (req.url ~ "(?i)\.(png|gif|jpeg|jpg|ico|swf|css|js|html|htm)(\?[a-z0-9]+)?$")
{
unset req.http.Cookie;
}
# !! Do not cache application area
if (req.url ~ "(^/app.php|^/app_dev.php|^)/([a-z]{2})/(payment|order|booking|media|autocomplete|monitor).*")
{
return (pass);
}
# !! Do not cache admin area
if (req.url ~ "(^/app.php|^/app_dev.php|^)/admin" || req.url ~ "(^/app.php|^/app_dev.php|^)/(([a-z]{2})/admin)")
{
return (pass);
}
# !! Do not cache security area
if (req.url ~ "(^/app.php|^/app_dev.php|^)/(([a-z]{2}/|)(login|logout|login_check).*)")
{
return (pass);
}
# Do not cache editor logged-in user sessions
if (req.http.Cookie ~ "(sonata_page_is_editor)")
{
return (pass);
}
return (lookup);
}
sub vcl_hit {
if (req.request == "PURGE")
{
purge;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE")
{
purge;
error 200 "Purged.";
}
}

Теперь все готово к запуску Varnish. Введите команду:

/etc/init.d/varnish restart

4: Проверка состояния приложения

Запустите следующие команды, чтобы убедиться, что Apache и Varnish привязаны к правильным портам.

# Apache:
netstat -lp | grep apache2
# Varnish:
netstat -lp | grep varnish

Вы получите примерно такой вывод:

tcp    0    0    localhost:8000    *:*     LISTEN   xxxx/apache2
-- or --
tcp6   0    0    [::]:8000         [::]:*  LISTEN   xxxx/apache2
-- and --
tcp    0    0    localhost:6082    *:*     LISTEN   xxxx/varnishd
tcp    0    0    *:http            *:*     LISTEN   xxxx/varnishd
tcp6   0    0    [::]:http         [::]:*  LISTEN   xxxx/varnishd

Теперь Apache и Varnish обслуживают установку Drupal. Чтобы оптимизировать работу бэкэнда Drupal, попробуйте модуль Drupal для Varnish. Этот модуль обеспечивает интеграцию с админ-сокетом, что позволяет Drupal динамически аннулировать записи кэша, а также запрашивать состояние у интерфейса администратора Varnish и т.п.

Примечание: Если вы используете Drupal старше версии 7, этот модуль вам понадобится, потому что Drupal использует файлы cookie для посетителей.

5: Устранение неполадок и другие примечания

Как узнать дистрибутив Linux и его версию?

Чтобы узнать, какой дистрибутив и версию использует ваша машина, запустите команду:

cat /etc/*-release

Где научиться работать с виртуальными хостами Apache?

Больше информации о виртуальных хостах можно найти в следующих мануалах:

Как выбрать порт?

В целом вы можете использовать любой свободный порт. Но некоторых портов следует избегать, поскольку они могут вызвать конфликты с другими приложениями:

  • Порт 25 предназначен для SMTP
  • Порт 119 – NNTP
  • Порт 443 – стандартный порт HTTPS
  • 3306 – порт MySQL

Чтобы узнать о портах больше, обратитесь к Википедии.

Что такое демон?

В вычислительных технологиях демон представляет собой фоновый процесс, который запускается самостоятельно. В случае с Varnish демон работает непрерывно при компиляции конфигурационного файла VCL, выполняя предварительно установленные и скомпилированные инструкции так же, как веб-сервер.

Tags: , ,