Chapter 1. Описание проблемы и её решение.

Настроена связка NGINX + PHP-FPM. PHP-FPM слушает обращения работает через  unix socket:

listen.owner = php
listen.group = php
listen.mode = 666
listen = /var/run/php-fpm.sock
listen.backlog = 65535

Операционная система CentOS 6.5

NGINX настроен принимать входящие соединения на адресе test.local и передавать их на PHP-FPM

server {
    server_name test.local;
    root /home/vhosts/test;
    location / {
        fastcgi_pass unix:/var/run/php-fpm.sock;
        include fcgi-as.fconf;
    }
}

Параметры в fcgi-as.fconf всегда отдают все обращения файлу index.php

В файле index.php прописан маленький скрипт для теста:

<?
   $a = 0;
   for ($i = 0; $i < 100; $i++) {
      $a++;
   }
   echo $a;
?>

Для тестирования производительности используется программа OpenLoad — http://openwebload.sourceforge.net/

Программа собрана из исходников, для сборки пришлось её немного пропатчить, так как она во первых не компилировалась, а во вторых нельзя было указать дополнительные параметры для gcc через configure.

В файле /src/tmplchunk.h меняем строку:

virtual int CTmplChunk::Verify(const char*& pos, const char* parm);

На строку

virtual int Verify(const char*& pos, const char* parm);

После выполнения configure в файле /src/Makefile меняем строку:

CXXFLAGS = -g -O2

На строку:

CXXFLAGS = -g -O3 -march=native

Этого можно и не делать, но тогда программа немного подтормаживает и выполняет на 3-5% запросов меньше.

Важно: Не пытайтесь использовать openload или любую другую программу для тестирования Вашего сервера на windows, на этой OS Вы скорее упретесь в производительность Вашей windows машины чем в производительность Вашего сервера, а результаты не будут достоверными.

Выполняем компиляцию программы

configure

[Патчим файлы]

make
make install

И начинаем тестирование. Параметры программы:

openload [опции] URL [кол-во клиентов]
ОПЦИИ:
-t - Режим тестирования, в этом режиме не будет производиться тестирования производительности, 
     а вместо этого будет отображен полный ответ от сервера включая заголовки. Это может быть
     полезно если Вы хотите проверить правильность введенного URL.
-h header value - Дополнить каждый запрос заголовком header со значением value 
                  -h User-Agent "MSIE 5.0"
-l time - время time в секундах в течении которого выполнять тестирование
-o outputmode - режим вывода результата, в данный момент поддерживается только csv

ОПИСАНИЕ РЕЗУЛЬТАТА:
MaTps - Скользящее среднее значение TPS за последние 20 секунд.
Tps - Кол-во запросов которые клиенты успели выполнить за последнюю секунду
Resp Time - Серднее время ответа по всем запросам за последнюю секунду
Err - Процент запросов которые были выполнены с ошибкой (код ответа HTTP отличный от 200)
Count - Общее кол-во выполненных запросов с начала тестирования
Total TPS - Среднее значение TPS за все тестирование
Avg. Response Time - Среднее время ответа за все тестирование в секундах
Max. Response Time - Максимальное время ответа за все тестирование в секундах

Выполняем команду:

openload -l 1 http://test.local 1

Пока всё хорошо:

URL: http://test.local:80/
Clients: 1
Time Limit: 1 sec.
MaTps 1060.00, Tps 1060.00, Resp Time  0.001, Err   0%, Count  1060
Total TPS: 1058.94
Avg. Response time:  0.001 sec.
Max Response time:   0.009 sec
Total Requests:    1060
Total Errors:         0

Усложняем задачу:

openload -l 1 http://test.local 200

И получаем проблему:

URL: http://test.local:80/
Clients: 200
Time Limit: 1 sec.
MaTps 1613.00, Tps 1613.00, Resp Time  0.120, Err  13%, Count  1613
Total TPS: 1531.81
Avg. Response time:  0.120 sec.
Max Response time:   0.320 sec
Total Requests:    1613
Total Errors:       214

В логе nginx видим строчки:

2014/10/17 12:52:34 [error] 8740#0: *720283 connect() to unix:/var/run/php-fpm.sock failed 
(11: Resource temporarily unavailable) while connecting to upstream,

Проиходит это потому что операционная система отвергает попытки nginx подключиться к unix сокету.

Причина либо превышено максимальное кол-во соединений к сокету либо максимальное кол-во не обработанных соединений к сокету.

Проверяем лимиты:

sysctl net.core

Нас интерисуют строки:

net.core.somaxconn = 128
net.core.netdev_max_backlog = 200

Из-за них и происходит ошибка, так как максимальное кол-во соединений 128 а максимум не обработанных 200

Меняем лимиты, в файл /etc/sysctl.conf прописываем строки

net.core.somaxconn = 20000
net.core.netdev_max_backlog = 65535

Применяем параметры

sysctl -p

Перезапускаем php-fpm

service php-fpm restart

Запускаем наше тестирование:

openload -l 1 http://test.local 200

Видим что все в порядке:

URL: http://test.local:80/
Clients: 200
Time Limit: 1 sec.
MaTps 1423.00, Tps 1423.00, Resp Time  0.133, Err   0%, Count  1423
Total TPS: 1421.58
Avg. Response time:  0.133 sec.
Max Response time:   0.276 sec
Total Requests:    1423
Total Errors:         0

Вот и все, проблема решена, а заодно мы получили замечательную утилиту openload для последующего тестирования и оптимизации производительности нашего сервера.

Один комментарий к “Ошибка NGINX — 11: Resource temporarily unavailable — На связке NGINX + PHP-FPM через unix socket”

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

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

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.