Ошибка

2014/10/03 14:21:00 [error] 549033#0: *10466327 upstream timed out (110: Connection timed out) while reading response header
from upstream, client: 95.xxx.xxx.xxx, server: _, request: "GET /xxxrend.php HTTP/1.1", upstream:
 "http://201.45.xxx.xxx:80/xxxrend.php", host: "domain.ru"

если nginx проксирует динамику на apache, то решается добавлением и увеличением директив:

   location / {
       proxy_connect_timeout 300;
       proxy_send_timeout 300;
       proxy_read_timeout 300;
   }

С оф. сайта:

Синтаксис:	proxy_read_timeout время;
Умолчание:
proxy_read_timeout 60s;
Контекст:	http, server, location
Задаёт таймаут при чтении ответа проксированного сервера. Таймаут устанавливается не на всю передачу ответа, а только
между двумя операциями чтения. Если по истечении этого времени проксируемый сервер ничего не передаст, соединение
 закрывается.

Много раз наблюдал, когда системный администратор для того, чтобы узнать, сколько запросов приходит ему на nginx за секунду, сидит и выгрепывает определенную секунду из лога, после чего делает | wc -l. Не знаю, зачем так извращаться, если есть pv.
Вообще pv позволяет посчитать, сколько строчек в секунду появляется в файле (если быть занудой — то сколько строчек в секунду подается ему на STDIN). Легко предположить, что при правильном access.log’e у nginx’a количество новых строчек == количеству отправленных ответов на запросы. А при ещё более правильном — количество запрошенных страниц.
Вообще эту штуку можно натравить на любой лог, фантазируйте сами.

Для начала поставим pv:
<strong>root@debian:~# aptitude install pv</strong>
Самый простой пример:
<strong>root@debian:~# tail -f /var/log/nginx/access.log | pv -lr</strong>
Где-то там внизу у нас замелькают какие-то цифры. При желании их можно разглядеть. Плюс этой команды в том, что мы можем одновременно видеть, что происходит в логе.

Представим, что нам не нужно смотреть, что происходит в самом логе. Сделаем так:
<strong>root@debian:~# tail -f /var/log/nginx/access.log | pv -lr >/dev/null</strong>
[3.94/s ]

Всё хорошо, но такая статистика — цифры в вакууме. Значение будет скакать от нуля до пикового.
Нам нужна усредненная статистика, по количеству строк в секунду, за последние 30 секунд:
<strong>root@debian:~# tail -f /var/log/nginx/access.log | pv -lr -i 30 >/dev/null</strong>
[0.933/s ]

Первое значение появится через 30 секунд, потом каждые 30 секунд будет обновляться. Такое значение колеблется намного меньше и ему уже можно верить при озвучивании цифр.
Запустив такую штуку в скрине с -i 86400 мы получим усредненное значение за сутки.

Ну и напоследок. Вам никто не запрещает использовать grep. Например, чтобы отследить количество обращений к одной странице или количество хитов с определенного адреса.
Делать это просто:
<strong>root@debian:~# tail -f /var/log/nginx/access.log | grep 192.168.0.10 | pv -lr -i 30 >/dev/null</strong>
[0.125/s ]
Здесь мы видим, что хост 192.168.0.10 последние 30 секунд обращался к нам с частотой 0.125 запроса в секунду.

Или так:
<strong>root@debian:~# tail -f /var/log/nginx/access.log | grep ""-"" | pv -lr -i 30 >/dev/null</strong>
[137.124/s ]
137.124 запроса в секунду с пустым реферером. Имеет смысл запретить на время коннекты с пустым реферером, не правда ли?

И grep -v тоже никто не запрещает использовать:
<strong>root@debian:~# tail -f /var/log/nginx/access.log | grep -v "/index.php" | pv -lr -i 30 >/dev/null</strong>
[15.541/s ]
Здесь мы видим 15.541 запроса в секунду к страницам, кроме index.php (в т.ч. и без index.php?чтототам).

Пользуйтесь на здоровье и поменьше вам ddos’ов, по которым нужно писать отчеты.

xCache — это программа из серии тех, что кешируют байт-код php для оптимизации и ускорения выполнения скриптов. Как, например, eAccelerator или PHP-APC.

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

Нет смысла долго задерживаться на установке: всё делается стандартно.

aptitude install php5-xcache

Основные настройки кэша

Первоочередной задачей будет указание основных настроек для работы. Откройте в вашем любимом редакторе файл /etc/php5/mods-available/xcache.ini. Все параметры собраны по группам. В данный момент нам нужна группа [xcache]

xcache.size = 32M

Данная директива указывает общий объём памяти для кэша. По-умолчанию 16 мегабайт.

xcache.count = 1

Указывается по количеству процессоров (ядер). Два ядра — ставим 2. И так далее. Или два одноядерных процессора.

xcache.ttl = 0

Время жизни кэша. Иногда может потребоваться очистка кэша через определённый промежуток времени. Значение указывается в секундах.

Рассмотрим параметры, необходимые для кэширования переменных. В определённых условиях, это тоже может пригодится.

xcache.var_size = 8M

Общий объём памяти, выделяемой для кэша переменных. По-умолчанию 0 — отключено.

xcache.var_count = 1

Эта переменная аналогична xcache.count.

xcache.var_ttl = 0

Тут тоже можно привести аналогию с переменной xcache.ttl: задаёт время жизни кэша переменных.

xcache.var_maxttl = 0

Эта переменная указывает максимальное время жизни кэша.

XCache Optimizer

Иногда может потребоваться включить встроенный в xCache оптимизатор. Для этого следующую директиву нужно перевести из состояния off в состояние on.

xcache.optimizer = on

Админ-панель для xCache

xCache поставляется вместе с панелью управления, позволяющей просматривать статистику. У меня связка nginx+php-fpm, пример будет написан с учётом этого.

Прежде всего настраиваем nginx. Здесь потребуется использование alias для location.

location /x/ {
alias /usr/share/xcache/admin/;

location ~ .php$ {
fastcgi_index index.php;
fastcgi_pass unix:/run/php-fpm.sock;
include fastcgi_params;
fastcgi_param PHP_ADMIN_VALUE "open_basedir=/usr/share/xcache/admin/:/var/php-temp-dir/";
fastcgi_param SCRIPT_FILENAME $request_filename;
}
}

Прописываем конфигурацию для любого виртуального хоста, перезапускаем nginx: service nginx reload. Далее в браузере открываем страницу http://example.com/x/mkpassword.php. Example.com замените на адрес вашего сайта, для которого вы создали алиас.

При помощи данного скрипта нужно создать md5-хеш пароля, который будет использоваться при аутентификации в админ-панели xCache. Достаточно указать пароль, нажать кнопку «Отправить запрос» и полученный результат скопировать.

После всех этих действий открываем файл /etc/php5/mods-available/xcache.ini, в группе [xcache.admin] редактируем необходимые параметры.

xcache.admin.user = «username»

Указываем имя пользователя, у которого будет доступ к админке.

xcache.admin.pass = «…»

Здесь в кавычках нужно указать md5-хеш пароля пользователя.

Сохраняем отредактированный файл и перезапускаем apache, php-cgi или php-fpm.

Теперь админка xcache должна быть доступна по адресу http://example.com/x/. Попробуйте авторизоваться и просмотреть статистику.

В Debian Wheezy php-fpm присутствует в основном репозитории. А это значит, что больше не приходится пользоваться сторонними репозиториями, типа DotDeb, для настройки и использования этого замечательного модуля.

Статья посвящается, большей частью, настройке php-fpm на debian, не рассматривая установку дополнительных сервисов, типа mysql, nginx и чего-то там ещё. Для nginx будет приведён лишь пример используемой мной конфигурации.

Установка

Как и в любом другом случае, первым делом нужно установить требуемые пакеты. Касательно дополнительных модулей, выбор, в основном, зависит от технических требований к сайту. В этом примере будет установлен как сам модуль php-fpm, так и модули для работы с mysql, изображениями (библиотека gd), curl, который требуется для многих cms.

apt-get install php5-fpm php5-mysqlnd php5-curl php5-gd

Конфигурационные файлы располагаются в каталоге /etc/php5/fpm/.

Настройка

Php-fpm изначально поставляется с одним пулом www в качестве примера работы. Можно отредактировать конфигурационный файл этого пула для себя, либо создать новый пул, основываясь на конфигурации существующего.

Давайте откроем конфигурационный файл /etc/php5/fpm/pool.d/www.conf, рассмотрим некоторые переменные и подберём для них значения.

Первая переменная — это имя пула. Имя заключается в квадратные скобки.

[www]

Если вам нужно создать новый пул, то создайте в папке /etc/php5/fpm/pool.d/ файл, poolname.conf, и укажите в нём имя пула в квадратных скобках: [poolname]. Имя файла может не совпадать с именем пула. Сделано это только для удобства. 🙂

Следует иметь в виду, что имя пула не может совпадать с именем пользователя — владельца сайтов или любого другого пользователя, существующего в системе.

Далее следуют переменные:

user = www-data
group = www-data

В качестве значения этих переменных указывается пользователь и группа, от имени которых будет работать пул. Здесь установите имя пользователя и группы, кто является владельцем файлов вашего сайта. То есть, пользователь, в чьей домашней директории хранится ваш сайт.

Это решит проблему с правами доступа к файлам сайта. Вам не придётся беспокоиться, выставлять каждый раз права на запись в какую-нибудь папку сайта для веб-сервера, и так далее.

listen = /var/run/php-$pool.sock

Оставляем unix-сокет. Переменная $pool будет заменена на имя пула.

listen.owner = www-data
listen.group = www-data

Тоже не требует изменений. Указывается пользователь и группа, которые становятся владельцами unix-сокета fpm при запуске. Необходимо, чтобы веб-сервер имел права на чтение сокета. Если изменить значения этих переменных на что-то другое, то пользователя www-data нужно будет добавить в группу владельца сокета и выставить права для чтения сокета группой.

В свою очередь, права на сокет устанавливаются переменной listen.mode. Не рекомендуется выставлять права 0666 из соображений безопасности.

pm = static. При старте fpm создаётся определённое количество процессов пула, которые обслуживают все поступающие запросы. Существуют также и другие варианты контроля дочерних процессов: dynamic и onedemand.

pm.max_children — количество создаваемых процессов. Необходимо вычислить сколько памяти занимает один процесс, потом разделить тот объем памяти который вы хотите выделить для php5-fpm, на объем одного процессора, получите количество pm.max_children (наример 1000мб/50мб=20)

Почему именно такой выбор? 🙂 Это самый экономный вариант. Каждый процесс пула будет занимать объём оперативной памяти, выделенный переменной memory_limit плюс несколько мегабайт на подключённые модули и т.п. При статичном варианте все запросы будут обрабатываться только созданными процессами, а новые порождаться (и занимать драгоценную память) не будут. В итоге получим фиксированное потребление памяти.

Вариант onedemand, по субъективным соображениям, не подходит потому, что каждый раз создание дочерних процессов при поступлении запросов будет занимать определённое время. Что скажется на работе сайтов.

pm.min_spare_servers = этот параметр начать с количество ядер процессора умножить на 2 (пример 1 ядро * 2 = 2)
pm.max_spare_servers = этот параметр количество ядер процессора * 1 (пример 1 *4 =4)
pm.start_servers = этот параметр вычисляется по формуле (pm.min_spare_servers+pm.max_spare_servers)/2 (пример (2+4)/2=4)
Итого на выходе получаем примерно конфигурацию для 1 ядерного процессора 1гб памяти (выделенные только под PHP5-FPM, возможно у вас 2Гб общей)
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 4

pm.max_requests — количество обработанных запросов, после которого процессы php-fpm будут перезагружены. Позволяет избежать утечек памяти при использовании сторонних библиотек. 1000—3000 запросов в зависимости от загруженности и объёма памяти на сервере.

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

 

slowlog = /var/log/php-$pool-slow.log

Определять, какие запросы считать медленными, поможет переменная request_slowlog_timeout. Здесь нужно указать время, по истечении которого информация о медленном запросе будет записана в лог-файл. Например:

request_slowlog_timeout = 10s

Последним шагом в настройке php-fpm будет установка некоторых дополнительных параметров php.ini, которые будут прописаны непосредственно в конфигурационном файле пула.

Каталог для размещения временных файлов:

php_admin_value[upload_tmp_dir] = "/var/tmp_dir"

Каталог для хранения файлов сессий:

php_admin_value[session.save_path] = "/var/save_path"

По соображениям безопасности, доступ к этим каталогам должен быть только у пользователя, с правами которого запускается пул php-fpm. Также не следует использовать один каталог и для хранения файлов сессий, и для временных файлов.

Ограничение памяти для выполнения скриптов следует подбирать, исходя из требований сайта. Для начала:

php_admin_value[memory_limit] = 50M

Обязательный параметр, который устраняет уязвимость:

php_admin_value[cgi.fix_pathinfo] = 0

Переменные sendmail_path и open_basedir не указываются специально. Они будут переданы в качестве параметров fast-cgi в конфигурационном файле nginx. Таким образом, для каждого конкретного сайта можно определить свою настройку. 🙂

После того, как все необходимые параметры прописаны, следует перезагрузить конфигурацию php-fpm командой:

service php5-fpm reload

Обработка php скриптов посредством nginx

Остаётся настроить nginx для работы с php-fpm. Конфиг не представляет собой какую-то особо сложную конструкцию.

location / {
root /var/www
...
location ~ .php$ {
try_files $uri =404;
fastcgi_pass unix:/run/php-www.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
fastcgi_ignore_client_abort off;
fastcgi_param PHP_VALUE "sendmail_path=/usr/sbin/sendmail -t -i -fmail@example.com";
fastcgi_param PHP_ADMIN_VALUE "open_basedir=/var/www/example.com/:/var/save_path/:/var/tmp_dir/";
}
...
}

Давайте рассмотрим детально некоторые параметры.

try_files $uri =404; отобразит ошибку 404 в браузере пользователя, вместо сообщения no input file specified, в случае, когда данная ошибка имеет место.

fastcgi_pass — путь к сокету php-fpm. Помните, какое имя мы ему дали в конфиге? /run/php-$pool.sock. Только вот nginx не понимает переменных fpm, поэтому указываем путь как есть: /run/php-www.sock. 🙂

fastcgi_pass unix:/run/php-www.sock;

Следующая переменная устанавливает путь к sendmail и параметр, указывающий адрес электропочты администратора сайта. Замените mail@example.com на что-то своё.

fastcgi_param PHP_VALUE "sendmail_path=/usr/sbin/sendmail -t -i -fmail@example.com";

Перечисляем каталоги для open_basedir: каталог с сайтом, каталог для сохранения временных файлов, каталог для файлов сессий.

fastcgi_param PHP_ADMIN_VALUE "open_basedir=/var/www/example.com/:/var/save_path/:/var/tmp_dir/";

Если требуется передать несколько параметров, до делать это следует так:

fastcgi_param PHP_ADMIN_VALUE "sendmail_path=/usr/sbin/sendmail -t -i -fmail@example.comnopen_basedir=/var/www/example.com/:/var/save_path/:/var/tmp_dir/";

Как можно заметить, параметры разделяются при помощи переноса строки: n.

Сохраняем все проделанные изменения и перезапускаем nginx.

service nginx reload
Посмотреть память отведенную PHP-FPM child processes
ps -ylC php5-fpm --sort:rss | awk '!/RSS/ { s+=$8 } END { printf "%s\n", "Total memory used by PHP-FPM child processes: "; printf "%dM\n", s/1024 }'

Так же ,можем настроить PHP-FPM, для автоматической перезагрузки, если есть проблемы. В этом примере перезапуск будет произведен, если десять дочерних процессов умирают в течение 1 минуты, и мы ожидаем  10 секунд перед перезапуском.

Это глобальная конфигурация и принадлежит /etc/php5/fpm/php-fpm.conf :

emergency_restart_threshold 10
emergency_restart_interval 1м
process_control_timeout 10s

Зачем нужен Nginx?

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

Так же Nginx можно использовать в режиме FastCGI, при этом Apache вам не понадобится. Однако при этом режиме у PHP наблюдается ряд проблем, поэтому на помощь приходит php-fpm!

Однако мы сегодня поговорим о совместной установке с Apache, а не в режиме FastCGI. Более того, по задаче у нас эти веб-сервера будут находится на одном сервере, поэтому выделим для Nginx — 80, а для Apache — 88 порт!

Apache (см. схему)

nginx

 

web_sch_11

Установка Apache и Nginx

Ставим Apache:

FreeBSD:

cd /usr/ports/www/apache2
make config
make install clean

 

Debian:

Установка Apache

apt-get install apache2
[+mod_rewrite]
a2enmod rewrite

При этом буду установлены так же пакеты:

    • openssl

 

  • openssl-blacklist

 

 

  • ssl-cert

 

 

Если этого не произошло, то необходимо установить их самостоятельно:

sudo apt-get install openssl openssl-blacklist ssl-cert

Создание сертификатов для SSL

Создание ключа

Первым делом необходимо создать приватный ключ (private key):

$ openssl genrsa -des3 -out adminunix.ru.key 2048
Generating RSA private key, 2048 bit long modulus
............................................+++
.....................................+++
e is 65537 (0x10001)
Enter pass phrase for adminunix.ru.key:
Verifying - Enter pass phrase for adminunix.ru.key:

При создании ключа необходимо указать ключевую фразу (и запомнить ее).

Создание подписанного сертификата

После того, как сгенерирован ключ, можно создавать самоподписанный сертификат (CSR — Certificate Signing Reques):

$ openssl req -new -key adminunix.ru.key -out adminunix.ru.csr
Enter pass phrase for adminunix.ru.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:RU
State or Province Name (full name) [Some-State]:Russia
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:adminunix.ru
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:lists.adminunix.rulists.adminunix.rulists.adminunix.ru
Email Address []:ssl@lists.adminunix.rulists.adminunix.rulists.adminunix.ru
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Удаление пароля из ключа

Неприятной особенностью ключа с паролем является то, что Apache или nginx будет регулярно спрашивать пароль при старте. Очевидно, что это не очень удобно (если только кто-то не находится постоянно рядом на случай перезагрузки или аварийной остановки). Для удаления ключа из пароля необходимо выполнить следующее:

$ cp adminunix.ru.key adminunix.ru.key.orig
$ openssl rsa -in adminunix.ru.key.orig -out adminunix.ru.key
Enter pass phrase for adminunix.ru.key.orig: <пароль-который-указывался-при-создании-adminunix.ru.key>
writing RSA key

Генерация SSL сертификата

Далее, создаем сам SSL сертификат:

$ openssl x509 -req -days 365 -in adminunix.ru.csr -signkey adminunix.ru.key -out adminunix.ru.crt
Signature ok
subject=/C=RU/ST=Russia/O=adminunix.ru/CN=lists.adminunix.rulists.adminunix.rulists.adminunix.ru/emailAddress=ssl@lists.adminunix.rulists.adminunix.rulists.adminunix.ru
Getting Private key

Теперь есть все, что необходимо для создания SSL-соединений.

Правильное расположение SSL сертификатов

Заключительным шагом в создании SSL сертификата будет распределение полученных файлов в соответствующие директории. Во-первых, копируем сам сертификат:

$ sudo cp adminunix.ru.crt /etc/ssl/certs/

Во-вторых, копируем ключ:

$ sudo cp adminunix.ru.key /etc/ssl/private/

И в-третьих, удаляем, все то, что было создано в текущей директории:

$ rm adminunix.ru.crt adminunix.ru.key adminunix.ru.csr adminunix.ru.key.orig

 

Ставим Nginx:

FreeBSD:

cd /usr/ports/www/nginx
make config
make install clean

Debian:

 apt-get install nginx
 Конфиги -> /etc/nginx

Настройка Nginx

Отредактируем файл /usr/local/etc/nginx/nginx.conf

# пользователь и группа от которого запускается процесс
user  www-data;

# кол-во рабочих процессов. Обычно равно кол-ву ядер на машине
worker_processes  2;

# Лог для ошибок
error_log  logs/error.log;

events {

    # максимум рабочих соединений
    worker_connections  1024;

    # Метод обработки соединений
    # kqueue — эффективный метод, используемый во FreeBSD
    # Подробнее http://sysoev.ru/nginx/docs/events.html
    use kqueue;
}

http {

    # Подключаем таблицу mime
    include       mime.types;

    # mime-тип по умолчанию
    default_type  application/octet-stream;

    # Формат лог файла
    #log_format  main  '$remote_addr - $remote_user [$time_local] $request '
    #                  '"$status" $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    # Лог доступа всего веб-сервера
    #access_log  logs/access.log  main;

    # Директива задаёт таймаут при чтении заголовка запроса клиента
    client_header_timeout  3m;

    # Директива задаёт таймаут при чтении тела запроса клиента
    client_body_timeout    3m;

    # Директива задаёт таймаут при передаче ответа клиенту
    send_timeout           3m;

    # Директива задаёт таймаут, в течение которого keep-alive соединение с клиентом не будет закрыто со стороны сервера
    keepalive_timeout      2m;

    # Директива разрешает или запрещает использовать sendfile()
    sendfile        on;

    # Директива разрешает или запрещает использовать опции TCP_NOPUSH во FreeBSD

    #tcp_nopush     on;

    # Директива задаёт размер буфера для чтения заголовка запроса клиента
    #client_header_buffer_size    1k;

    # Директива задаёт максимальное число и размер буферов для чтения большого заголовка запроса клиента
    #large_client_header_buffers  4 4k;
    # Настройки сжатия
       gzip on;
       gzip_disable "msie6";
       ssi on;
       gzip_comp_level 3;
       gzip_proxied any;
       gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
 # Модуль позволяет описывать группы серверов, которые могут использоваться
 # в директивах proxy_pass и fastcgi_pass. upstream backend {
# Директива задаёт имя и параметры сервера. Обратите внимание, мы будем
# использовать имя "backend" в директиве proxy_pass server 127.0.0.1:88; } server {
# Слушать 80 порт listen 80;
# Использовать следующие хосты server_name adminunix.ru www.adminunix.ru;
# Кодировка #
charset koi8-r;
# Лог доступа для конкретного виртуального хоста
#access_log logs/host.access.log main;
# Максимальный размер тела запроса клиента client_max_body_size 101M;
# Разруливаем статику и динамку, смотрите описание ниже в этой статье! location ~* .(jpg|jpeg|gif|png|ico|css|bmp|swf|js)$ { root /home/adminunix/adminunix.ru; } location ~ /.ht { deny all; } #Секция описывает параметры, по которым фронтенд обменивается с бекендом,
#такие, как адресабекенда, параметры прямого редиректа, парарметры передачи заголовков,
#максимальный размер принимаемых файлов и пр.
}
}

Создаем файл конфигурации proxy.conf:
$ sudo mcedit /etc/nginx/proxy.conf

Должен иметь следующий вид:

proxy_redirect              off;
proxy_set_header            Host $host;
proxy_set_header            X-Real-IP $remote_addr;
proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size        10m;
client_body_buffer_size     128k;
proxy_connect_timeout       90;
proxy_send_timeout          90;
proxy_read_timeout          90;
proxy_buffer_size           4k;
proxy_buffers               4 32k;
proxy_busy_buffers_size     64k;
proxy_temp_file_write_size  64k;

Настройка виртуального хоста в Nginx

Создаем файл виртуального хоста:

$ sudo mcedit /etc/nginx/sites-available/adminunix.ru.vhost

Файл следующего вида:

upstream backend {
  # Адрес back-end'a
  server 127.0.0.1:8080;
}

server {
    listen   80;
    server_name www.adminunix.ru adminunix.ru;

    access_log /home/site/adminunix.ru/logs/nginx_access.log;
    error_log /home/site/adminunix.ru/logs/nginx_error.log;

    # Перенаправление на back-end
    location / {
        proxy_pass  http://backend;
        include     /etc/nginx/proxy.conf;
    }

    # Статическиое наполнение отдает сам nginx
    # back-end этим заниматься не должен
    location ~* .(jpg|jpeg|gif|png|ico|css|bmp|swf|js)$ {
        root /home/site/adminunix.ru/static/;
    }
}

Создание виртуальных хостов в Nginx

Создаем описание двух виртуальных хостов:

$ sudo touch /etc/nginx/sites-available/adminunix.ru.vhost
$ sudo touch /etc/nginx/sites-available/lists.adminunix.ru-ssl.vhost

Создаем необходимые директории двух виртуальных хостов:

$ sudo mkdir -p /usr/local/hosting/www/adminunix.ru/logs
$ sudo mkdir -p /usr/local/hosting/www/adminunix.ru/apache
# создаем html файл, который будет отражаться при обращении к "http://adminunix.ru"
$ sudo touch /usr/local/hosting/www/adminunix.ru-1/index.html
$ sudo mkdir -p /usr/local/hosting/www/lists.adminunix.ru/logs
$ sudo mkdir -p /usr/local/hosting/www/lists.adminunix.ru/apache
# создаем html файл, который будет отражаться при обращении к "http(s)://lists.adminunix.ru"
$ sudo touch /usr/local/hosting/www/lists.adminunix.ru/index.html
$ sudo chown www-data:www-data -R /usr/local/hosting/www/

Настройка стандартного виртуального хоста в Nginx

Файл настройки должен иметь следующий вид:

#$ sudo cat /etc/nginx/sites-available/adminunix.ru.vhost
upstream backend {
  # Адрес back-end'a
  server 127.0.0.1:8080;
}

server {
    listen   80;
    server_name adminunix.ru;

    access_log /usr/local/hosting/www/adminunix.ru/logs/nginx_access.log;
    error_log /usr/local/hosting/www/adminunix.ru/logs/nginx_error.log;
    # Перенаправление на back-end
    location / {
        proxy_pass  http://backend;
        include     /etc/nginx/proxy.conf;
    }
    # ...
}

Настройка виртуального хоста в Nginx с поддержкой SSL

Файл настройки должен иметь следующий вид:

#$ sudo cat /etc/nginx/sites-available/listen.adminunix-ssl.vhost
upstream backend1 {
  # Адрес back-end'a
  server 127.0.0.1:8080;
}

server {
    listen   80;
    server_name lists.adminunix.ru;

    access_log /usr/local/hosting/www/lists.adminunix.ru/logs/nginx_access.log;
    error_log /usr/local/hosting/www/lists.adminunix.ru/logs/nginx_error.log;

    # Перенаправление на back-end
    location / {
        proxy_pass  http://backend1;
        include     /etc/nginx/proxy.conf;
    }
    # ...
}

server {
    listen   443;
    server_name lists.adminunix.ru;

    ssl    on;
    ssl_certificate         /etc/ssl/certs/lists.adminunix.ru.crt;
    ssl_certificate_key     /etc/ssl/private/lists.adminunix.ru.key;

    access_log /usr/local/hosting/www/lists.adminunix.ru/logs/nginx_ssl_access.log;
    error_log /usr/local/hosting/www/lists.adminunix.ru/logs/nginx_ssl_error.log;
    # Перенаправление на back-end
    location / {
        proxy_pass  http://backend1;
        include     /etc/nginx/proxy.conf;
    }
    # ...
}

В отличие от конфигурации для adminunix.ru тут уже появляется описание для 443 порта. Идея проста — ssl-соединение создает nginx, а вот данные по этому соединению передает уже apache.

Включение хостов и перезапуск Nginx

После того, как настройки сделаны, необходимо сделать виртуальные хосты достпными и перезапустить nginx:

$ sudo ln -s /etc/nginx/sites-available/adminunix.ru.vhost /etc/nginx/sites-enabled/adminunix.ru
$ sudo ln -s /etc/nginx/sites-available/adminunix.ru-ssl.vhost /etc/nginx/sites-enabled/adminunix.ru-ssl.vhost
$ sudo /etc/init.d/nginx restart

Создание виртуальных хостов в Apache

Так как ssl-соединениями занимается nginx, то apache остается всего лишь работать на не стандартном порту (например, 8080) и обрабатывает входящие содинения. Создаем файлы виртуальных хостов Apache:

#$ sudo cat /etc/apache2/sites-available/adminunix.ru.vhost
<VirtualHost *:8080>
  # Осн. настройки домена
  ServerAdmin admin@adminunix.ru
  ServerName adminunix.ru

  DocumentRoot /usr/local/hosting/www/adminunix.ru/
  <Directory /usr/local/hosting/www/adminunix.r/>
      Order deny,allow
      Allow from all
  </Directory>

  ErrorLog  /usr/local/hosting/www/adminunix.ru/logs/apache_error.log
  CustomLog /usr/local/hosting/www/adminunix.ru/logs/apache_access.log combined
  # Остальные настройки
  # ...
</VirtualHost>

Второй хост:

#$ sudo cat /etc/apache2/sites-available/lists.adminunix.ru
<VirtualHost *:8080>
  # Осн. настройки домена
  ServerAdmin admin@lists.adminunix.ru
  ServerName lists.adminunix.ru

  DocumentRoot /usr/local/hosting/www/lists.adminunix.ru/
  <Directory /usr/local/hosting/www/lists.adminunix.ru/>
      Order deny,allow
      Allow from all
  </Directory>

  ErrorLog  /usr/local/hosting/www/lists.adminunix.ru/logs/apache_error.log
  CustomLog /usr/local/hosting/www/lists.adminunix.ru/logs/apache_access.log combined
  # Остальные настройки
  # ...
</VirtualHost>

Далее, необходимо включить хосты и перегрузить apache:

$ sudo a2ensite adminunix.ru
$ sudo a2ensite lists.adminunix.ru
$ sudo /etc/init.d/apache2 restart

Проверка SSL соединения

Чтобы проверить корректность настройки SSL достаточно открыть в браузере https://lists.adminunix.ru/. Так как используется самоподписанный сертификат, то браузер, вероятнее всего, выдаст предупреждение, что подлинность сервера не может быть проверена, и предоставит возможность просмотреть сертификат. В случае, если текущий домен не совпадает с тем, что указан «Common Name», может быть выдано еще одно предупреждение.

Самоподписанных сертификтов как правило хватает для административных зон на сайтах. При использовании коммерческих сертификатов никаких предупреждений выдаваться не будет.

Для более тонкой настройки SSL или для решения проблем в TLS/SSL-соединениях следует пользоваться набором утилит openssl. Например:

$ openssl s_client -connect lists.adminunix.rulists.adminunix.rulists.adminunix.ru:443

После конфигурации необходимо перезагрузить Nginx

/usr/local/etc/rc.d/nginx restart

Nginx: Отдаем статику

web_sch_2 С помощью этих правил разруливаем запросы на отдачу статику и динамического контента

# Следующие расширения файлов (jpg, jpeg, gif, png, ico, css, bmp, swf и js) отдаются напрямую, без участия Apache.
location ~* .(jpg|jpeg|gif|png|ico|css|bmp|swf|js)$ {
    root /home/adminunix/adminunix.ru;
}

# htaccess и htpasswd не отдаем
location ~ /.ht {
       deny  all;
}

# Все остальное разруливает бекенд (Apache)
location / {

        # Адрес бекенда. Параметры бекенда перечислили в директиве "upstream" (см. выше в статье)
        proxy_pass http://backend/;

        # Заголовок Host
        proxy_set_header Host $host;

        # Заголовок X-Real-IP
        proxy_set_header X-Real-IP $remote_addr;

        # Заголовок X-Forwarded-For
        proxy_set_header X-Forwarded-For $remote_addr;

        # Директива задаёт таймаут для соединения с проксированным сервером, сек
        proxy_connect_timeout 120;

        # Директива задаёт таймаут при передаче запроса проксированному серверу, сек
        proxy_send_timeout    120;
        # Директива задаёт таймаут при чтении ответа проксированного сервера, сек
        proxy_read_timeout    180;
}

Настройка Apache

Редактируем файл /usr/local/etc/apache2/httpd.conf

# Меняем порт с 80 на 88
Listen 88

Тоже самое делаем и в httpd-vhosts.conf для ваших хостов.

Если у вас появляется следующая ошибка:
> [warn] (2) No such file or directory:
> Failed to enable the ‘httpready’ Accept Filter

то вам следует подгрузить модуль
# kldload accf_http

Установка и настройка RPAF или даешь верный REMOTE_ADDR!

Так как у нас появился в цепи дополнительный элемент в виде фронтенд-сервера, то теперь в REMOTE_ADDR у нас не пользовательский IP, а IP-адрес фронтенд-сервера (на котором расположен Nginx). Поэтому на помощь приходит RPAF, он берет тело заголовка X-Forwarded-For, присланного от фронтенда и формирует на бекенде из него REMOTE_ADDR.

Таким образом заголовок REMOTE_ADDR снова имеет пользовательский IP!

Устанавливаем модуль RPAF
FreeBSD

cd /usr/ports/www/mod_rpaf2
make install clean

Debian

apt-get install libapache2-mod-rpaf
a2enmod rpaf
mod_rpaf2 - для apache2, а для первого индейца надо mod_rpaf

Настраиваем RPAF, редактируем httpd.conf, добавляем в конец файла:

# Включаем модуль
RPAFenable On
# Доводит до ума X-Host
RPAFsethostname On
# Адрес фронтенда (nginx)
RPAFproxy_ips 82.146.61.55 127.0.0.1
# Имя отправляемого заголовка
RPAFheader X-Forwarded-For
или
RPAFheader X-Real-IP

После конфигурации необходимо перезагрузить Apache

apachectl restart

Debian 

/etc/init.d/apache2 restart
/etc/init.d/nginx restart

Ну вот вроде и все, смотрите ниже дополнительную литературу и задавайте вопросы в камменты!

Полезные материалы по Nginx

Полезные ссылки
Пример конфигурации nginx
Настройка виртуальных серверов
Отличная статья с Хабра: Тюнинг nginx

Устал я от того что мой блог долго грузится, но менять движок с WordPress на что-либо другое пока нет времени, а переезд на новый более мощный сервер всё время затягивается и решил прикрутить кеширование на стороне Nginx. Так как блог работает на fastcgi, то буду использовать fastcgi_cache, если вы используете связку Nginx+Apache, то вам следует использовать proxy_cache, как я понял там отличий особых нет.

Некоторые блоки мне всетаки надо оставить вне кеша, поэтому буду использовать ssi.

Настройка

У меня много хостов на одном сервере, но мне надо настроить кеш только для одного хоста. Определим кеш для моего блога в nginx.conf, секция http:

fastcgi_cache_path /var/cache/nginx/adw0rd
    levels=1:2
    keys_zone=adw0rd:16m
    max_size=256m
    inactive=1d;

Где,

fastcgi_cache_path  — путь до каталога кеша, создайте его заблаговременно.
levels= — разделять файлы кеша на сабкаталоги заданного уровня, то есть «1:2» — это так:
/0/ab/b7f54b2df7773722d382f4809d650ab0

либо так, если не указывать LEVEL, то есть levels оставить пустым (levels=):

/b7f54b2df7773722d382f4809d650ab0

max_size — максимальный размер кеша.
incative — время жизни кеша.

Настройка виртуального хоста

Я разделяю конфиги на основной (nginx.conf) и на хосты (adw0rd.conf, pyha.conf, etc). Сейчас мы разберемся с adw0rd.conf:

server {
    # Порт который слушаем
    listen 80;
    # Имя хоста
    server_name adw0rd.ru;
    # Путь до htdocs (document_root)
    root /path/to/www;

    # включаем использование ssi
    ssi on;

    location / {
        # Если такой файл не существует физически, то переходить на крайний аргумент, то есть @wordpress
        try_files $uri @wordpress;
    }

    # обработчик для wordpress
    location @wordpress {

        # Проксируем на php-fpm
        fastcgi_pass php-fpm;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root/index.php;
        fastcgi_param SCRIPT_NAME /index.php;

        # Настройки кеширования
        fastcgi_temp_path /tmp/nginx 1 2; # Каталог для хранение временных файлов
        fastcgi_cache adw0rd; # Имя зоны кеша
        fastcgi_cache_key "$request_method|$host|$request_uri"; # Из этих данных строится хеш
        fastcgi_hide_header "Set-Cookie"; # Не передавать клиенту заголовки кук
        fastcgi_cache_min_uses 1; # Кол-во запросов, после которых ответ будет закеширован
        fastcgi_cache_valid 10m; # Время жизни кеша
        fastcgi_cache_use_stale error timeout invalid_header http_500; # Случаи при которых будет использоватся старый кеш

    }

    # обработчик для динамических данных на странице, ниже я покажу как юзать это
    location ~ ^/ssi/ {
        fastcgi_pass php-fpm;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # Обработчик *.php файлов, например "wp-comments-post.php"
    location ~ .php$ {

        # если файл физически не существует, то переходим в @wordpress
        try_files $uri @wordpress;
        # иначе обрабатываем запрос
        fastcgi_pass php-fpm;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Обо всех директивах можете прочитать в оф. доке Директивы модуля ngx_http_fastcgi_module.

Тестирование

Перезагружаем Nginx:

nginx -s reload

Для тестирования кеша я встроил в шаблон html-комментарий, который формирую так:

<!-- cache: <?php echo time() ?> -->

И теперь вижу в сорце странице закешировалась страница или нет.

Вставка динамических блоков при помощи SSI

Отредактируйте шаблон своей страницы и вставьте нечто подобное:

<!-- uncached_data: <!--# include virtual="/ssi/uncached.php" wait="no" --> -->

Теперь приведите файл «/ssi/uncached.php» к следующему виду:

<?php
echo time();

Так как у нас есть обработчик действующий для /ssi/* и он не отдает кешированные данные, то у нас будет подгружатся динамика, все просто!

Дополнение

 

Директива fastcgi_ignore_headers для игнорирования инструкци от FastCGI-сервера

Директива fastcgi_ignore_headers запрещает обработку некоторых строк заголовка из ответа FastCGI-сервера. В директиве можно указать строки «X-Accel-Redirect», «X-Accel-Expires», «Expires» и «Cache-Control».

fastcgi_ignore_headers Expires Cache-Control;

То есть указываем Nginx кэшировать страницы в любом случае, независимо от заголовков кэширования выставленных FastCGI-сервером.

Директивы fastcgi_cache_bypass и fastcgi_no_cache

Директива задаёт условия, при которых ответ не будет браться из кэша. Если значение хотя бы одной из строк переменных не пустое и не равно «0», то ответ не берётся из кэша:

fastcgi_cache_bypass $cookie_session $cookie_nocache;

Директива задаёт условия, при которых ответ не будет сохраняться в кэш. Если значение хотя бы одной из строк переменных не пустое и не равно «0», то ответ не будет сохранён:

fastcgi_no_cache $cookie_session $cookie_nocache;

Управление кеширование через заголовок X-Accel-Expires

Будем управлять кеширование из PHP:

<?php
header("X-Accel-Expires: $seconds"); // ставим на $seconds секунд
header("X-Accel-Expires: 0"); // или отключаем кеширование для определенной страницы

Принудительное обновление кэша

Обновим наш bypass, добавим еще одну переменную для заголовка «X-Update»:

fastcgi_cache_bypass $cookie_session $http_x_update;

Ну а теперь обновим кеш:

curl -s -o /dev/null -H "X-Update: 1" example.com

Как и рекомендуют авторы статьи необходимо изменить «$http_x_update» и «X-Update» на что-то своё, чтобы скрипткидесы не баловались.

Полезные материалы

Вот небольшой список статей, который вам могут пригодится:

  • Директивы модуля ngx_http_fastcgi_module (оф. документация)
  • Описание модуля NginxHttpFcgiModule на wiki.nginx.org
  • Кеширование FastCGI-запросов в nginx
  • 56. Подводные камни при использовании кэширования в nginx
  • Nginx. Использование PHP в режиме FastCGI с помощью php-fpm