суббота, 20 апреля 2013 г.

Балансировка нагрузки на веб-сайт

DNS

Самый простой способ балансирования нагрузки и распределения запросов между веб-серверами - использование механизма round robin DNS.
Спецификация стандарта DNS позволяет указать несколько разных IN A записей для одного имени. Например:
www  IN A  10.0.0.1 
www  IN A  10.0.0.2
В этом случае DNS-сервер в ответ на запрос разрешения имени в IP-адрес будет выдавать не один адрес, а весь список:
# host www.domain.local 
www.domain.local has address 10.0.0.1 
www.domain.local has address 10.0.0.2
При этом с каждым новым запросом последовательность адресов в списке в ответе будет меняться. Таким образом клиентские запросы будут распределяться между разными адресами и будут попадать на разные серверы.
Использование round robin DNS - самый простой способ балансировки нагрузки, не требующий никаких дополнительных средств, однако он обладает целым рядом недостатков, поэтому мы рекомендуем использовать его только в том случае, если нет возможности применить какой-либо иной балансировщик.
Минусы применения round robin DNS:
  • нет четкого критерия выбора IP из списка клиентом (может выбираться первый элемент, может кэшироваться последнее выбранное значение, возможны иные варианты): все зависит от реализации конкретного клиента;
  • нет механизмов определения доступности узлов и возможности задания их "весов": в случае аварии на одном или нескольких узлах кластера нагрузка будет продолжать распределяться между рабочими и вышедшими из строя нодами;
  • длительное время кэширования ответов DNS: в случае аварии и изменении тех или иных записей в DNS потребуется некоторое время (зависит от настроек DNS) для обновления данных на всех клиентах.

nginx

Рассмотрим пример использования в качестве балансировщика http-сервера nginx. Для этих целей используется модуль ngx_http_upstream.
При использовании "1С-Битрикс: Веб-окружения" nginx уже установлен на серверах веб-кластера. И для распределения нагрузки можно использовать непосредственно один из серверов кластера. Однако для более простого, гибкого и удобного конфигурирования лучше использовать отдельный сервер с установленным nginx в качестве балансировщика.
В простейшем примере фрагмент конфигурационного файла nginx (/etc/nginx/nginx.conf), обеспечивающего распределение нагрузки между серверами, будет выглядеть так (помимо стандартных директив, определяющих, например, пути и формат log-файлов и т.п.):
http { 
    upstream backend { 
        server node1.demo-cluster.ru; 
        server node2.demo-cluster.ru; 
    } 

    server { 
        listen   80; 
        server_name  load_balancer; 

        location / { 
            proxy_set_header X-Real-IP $remote_addr; 
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
            proxy_set_header Host $host:80; 

            proxy_pass  http://backend; 
        } 

    } 
}
В секции upstream задаются адреса серверов, между которыми будет распределяться нагрузка.
В DNS имя сайта указывается на тот IP, на котором работает сервер с nginx, распределяющем нагрузку.
Если не указаны какие-либо дополнительные параметры, запросы распределяются между серверами по принципу round robin.
Однако с помощью модуля ngx_http_upstream можно реализовать и более сложные конфигурации.
  • В некоторых случаях бывает удобно передавать все запросы от одного клиента на один и тот же сервер, а между серверами распределять только запросы разных клиентов. Для реализации подобного функционала служит директива ip_hash. Пример:
    upstream backend 
    { 
        ip_hash; 
    
        server node1.demo-cluster.ru; 
        server node2.demo-cluster.ru; 
    }
    
    В этом случае распределение запросов основано на IP-адресах клиентов.
  • Если для узлов кластера используются серверы разной конфигурации (разной мощности), бывает полезно задать "вес" для тех или иных хостов, направляя на них больше или меньше запросов. Для этого служит параметр weight директивы server. Пример:
    upstream backend 
    { 
        server node1.demo-cluster.ru weight=3; 
        server node2.demo-cluster.ru; 
        server node3.demo-cluster.ru; 
    }
    
    В такой конфигурации каждые 5 запросов будут распределяться следующим образом:
    • 3 - на node1.demo-cluster.ru;
    • 1 - на node2.demo-cluster.ru;
    • 1 - на node3.demo-cluster.ru.
    Обратите внимание: для серверов, использующих метод распределения ip_hash, нельзя задать вес.
  • Можно настроить параметры, по которым будут определяться неработающие серверы. max_fails = число - задает число неудачных запросов к серверу в течение времени, заданного параметром fail_timeout, после которых он считается неработающим также в течение времени заданного параметром fail_timeout;
    fail_timeout = время Пример:
    upstream backend 
    { 
        server node1.demo-cluster.ru max_fails=3 fail_timeout=30s; 
        server node2.demo-cluster.ru max_fails=3 fail_timeout=30s; 
    }
    
    Если при запросе к серверу произошла ошибка, запрос будет передан на следующий сервер. Если произошло 3 ошибки в течение 30 секунд, то на 30 секунд сервер будет помечен неработающим, и в течение этого времени новые запросы не будут на него отправляться.

Комментариев нет:

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