Отказоустойчивость веб сервера Nginx, модуль ngx_http_upstream

Балансировка нагрузки и отказоустойчивость Nginx, реализуется с помощью специального модуля ngx_http_upstream. Директива upstream позволяют организовывать группы серверов ( upstream ), распределяя между ними запросы для проксирования в директивах proxy_pass и fastcgi_pass. Кроме того, это дает Nginx возможность, реагировать на нештатные ситуации в апстриме, например, в случае выхода из строя одного или нескольких серверов из группы, запрос будет отправлен на следующий, работающий сервер апстрима.

Итак, как это все организовано. Модуль веб сервера Nginx - ngx_http_upstream поддерживает следующие директивы конфигурационного файла:

upstream название { .... }
Работает в контексте http
Директива определяет группу серверов, между которыми будут распределяться запросы. Сервера, в свою очередь, задаются с помощью директивы server с соответствующими параметрами ( см. ниже ). В случае возникновения ошибки, в процессе работы с сервером, запрос отправляется на следующий сервер группы и так далее, по списку. Если не будет найден, ни один работающий сервер, клиенту будет отдан результат работы последнего сервера.
server название [ необязательные параметры ]
работает в контексте upstream

Данная директива определяет один сервер группы. В качестве имен серверов можно использовать: домен, IP адрес, порт или путь до файла unix-сокета. Имеет следующие параметры:

weight = число, так называемый вес сервера, на основании которого идет распределение запросов. Если параметр не указан, вес равен 1.

max_fails = число, задает число неудачных попыток обращения к серверу, в промежуток времени, установленный параметром fail_timeout, после которых, сервер считается неработающим, в течении времени, опять-же установленного параметром fail_timeout. Если параметр не указан, число попыток равно 1. Какую ситуацию считать ошибкой, в процессе работы с сервером из группы, определяют директивы proxy_next_upstream и fastcgi_next_upstream, в соответствующих блоках Location.

fail_timeout = время, интервал времени, в течение которого должно произойти, указанное параметром max_fails, число неудачных попыток обращения к серверу группы, а так-же, время, в течение которого, данный сервер, будет считаться неработающим. Если ничего не задано, данное время равно 10 секундам.

backup, определяет сервер как запасной. Будет использован в случае, отказа всех остальных серверов группы.

down , определяет сервер как всегда неработающий, используется с директивой ip_hash.

Группа серверов может представлять собой любую комбинацию из приведенного списка:

upstream test_upstream {
    server    127.0.0.1:8080 weight=3;
    server    test.domail.ru max_fails=5 fail_timeout=60s;
    server    unix:/tmp/fastcgi_socket fail_timeout=30s;

    server    backup.server.com backup;
}

В данном примере, 3 запроса будут отправлены на первый сервер, 1 на второй и 1 на третий, затем снова 3 на первый. Сервер backup.server.com, будет использоваться только в случае отказа всех серверов.

ip_hash
работает в контексте upstream
Директива определяет метод распределения запросов по серверам группы, на основании IP адреса клиента. Такой способ распределения запросов, гарантируется, что запросы клиента, будет обслуживать один и тот-же сервер. В случае отказа данного сервера, запросы перенаправлены на другой сервер группы и тоже с большой долей вероятности, будут обслужены одним и тем-же сервером. Обратите внимание, при данном методе распределения запросов, нельзя задать вес ( параметр weight ), сервера.

Теперь как это выглядит на практике. Операционная система FreeBSD 7.1 STABLE, фронтендом на внешнем IP адресе стоит Nginx/0.7.61, в качестве первого бакэнда, FastCGI сервер, работающий по TCP( локальный адрес 127.0.0.1, порт 9000 ), второй и третий бакэнды, FastCGI сервера PHP ( на unix-сокетах ).

Конфигурационный файл Nginx выглядит следующим образом:

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format upstream   '$upstream_addr | $request - [ $upstream_response_time ]';

Настройка формата логов. Здесь мы используем переменные модуля upstream, что-бы увидеть работу апстрима в лог файлах.
$upstream_addr - данная переменная содержит адрес и порт сервера или путь к файлу unix-сокета. Если в процессе обработки запроса, будет сделано обращение к нескольким сервера, они будут перечислены через запятую.
$upstream_status - содержит статус ответа сервера, если больше одного, так-же перечисляются через запятую.
$upstream_response_time - время ответа сервера с точностью до миллисекунд. От самого начала соединения с сервером-бакэндом до закрытия с ним соединения. Очень полезная переменная, для проверки скорости ответов бакэндов.
Кроме того, существуют переменные, $upstream_http_строка заголовка, содержащие строки заголовка, ответа сервера.

    sendfile        on;
    tcp_nopush     on;
    keepalive_timeout  0;
    gzip  on;

upstream fastcgi {
        server unix:/tmp/fastcgi_sock weight=4;
        server unix:/tmp/fastcgi2_sock max_fails=2 fail_timeout=30s;
        server 127.0.0.1:9000 backup;
}

Блок директивы upstream. Запросы в данном случае будут распределяться следующим образом, 4 запроса уйдут на первый сервер, 1 запрос на второй, снова 4 на первый и т.д.. Если вторым сервером, в течении 30 секунд, будет выдано 2 ошибки ( какие ситуации будут считаться ошибками, смотрите ниже ), он будет считаться неработающим в течении 30 секунд. Если оба сервера перестанут отвечать, будет задействован резервный сервер с пометкой backup.

    server {
        listen       192.168.50.20:80;
        server_name  nginx;

        access_log      logs/nginx_upstream_access.log  upstream; # Пишем логи в настроенном нами формате.

        root   /usr/home/test/public_html;

        location / {
            index  index.php index.html index.htm;
        }

        location ~ \.php$ {
            fastcgi_pass   fastcgi; # Передача запросов на нашу группу серверов
            fastcgi_next_upstream error timeout http_500 http_404;
Какую ситуацию считать ошибкой бакэнд-сервера и отправлять запрос на следующий сервер группы. Возможные значения:

error - ошибка соединения, чтения заголовка или передачи ответа.
timeout  - таймаут во время соединения, чтения заголовка или передачи ответа. 
invalid_header - возврат пустого или неправильного заголовка.
http_500 - ответ с кодом 500.
http_503 - ответ с кодом 503.
http_404 - ответ с кодом 404.
off - не передавать запрос следующему серверу.

Передача запроса следующему серверу, возможна только в случае, если клиенту еще ничего не отдано.
 
           fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }

        error_page  404              /404.html;
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/local/www/nginx-dist;
        }

        location ~ /\.ht {
            deny  all;
        }
    }
}

Теперь можно проверить работоспособность, как мы делали в предыдущих статьях, то есть запрашиваем через строку браузера простенький PHP файл и смотрим в логе logs/nginx_upstream_access.log, куда идут запросы. Для большего понимания работы данной схемы, можно поиграть с параметрами серверов апстрима, поотключать некоторые из них, что-бы увидеть, что происходит в случае сбоев.

Комментарии

Отправить комментарий

Содержание этого поля является приватным и не предназначено к показу.
Регистр имеет значение
 oooooo     oooo  oooo             .          .o.                    .oooooo..o 
`888. .8' `888 .o8 .888. d8P' `Y8
`888. .8' 888 oooo .o888oo .8"888. .oooo. Y88bo.
`888. .8' 888 .8P' 888 .8' `888. `P )88b `"Y8888o.
`888.8' 888888. 888 .88ooo8888. .oP"888 `"Y88b
`888' 888 `88b. 888 . .8' `888. d8( 888 oo .d8P
`8' o888o o888o "888" o88o o8888o `Y888""8o 8""88888P'


Введите код, изображенный в стиле ASCII-арт.