Балансування навантаження з допомогою Nginx

Автор | 01.12.2010

Переклад статті Use Nginx for Proxy Services and Software Load Balancing

Серед додаткових особливостей nginx є можливість використання його як проксі (front end proxy) для передачі запитів на інші веб-сервери, Nginx також може виступати в якості Front end інтерфейсу для кластеру з серверів і навіть для балансування навантаження (load balancer).

Розглянемо наступні витримки конфігурації, які описують кластер appcluster:

Уривок файлу : nginx.conf

http {
  # [...]

  upstream appcluster {
     server lollipop.ducklington.net:8801;
     server lollipop.ducklington.net:8802;
     server lollipop.ducklington.net:8803;
     server lollipop.ducklington.net:8804;
     server simons.ducklington.net:8801;
     server simons.ducklington.net:8802;
     server simons.ducklington.net:8803;
     server simons.ducklington.net:8804;
     }

  # [...]

  server {
    listen 21.43.56.87:80;
    server_name ducklington.org www.ducklington.org;

    location / {
       proxy_pass  http://appcluster;
       }
    }

    # [...]
  }

У цьому прикладі ми описали просте балансування по принципу round-robin за допомогою директиви upstream.

Всередині цього блоку ми описали вісім серверів, кожен з яких працює на різних хостах і портах.
Конфігурація блоку upstream повинна бути разташована на початку блоку http конфігураційного файлу nginx.conf.

Сервери, що працюють на портах з 8801 по 8804 на хостах lollipop.ducklington.net і simons.ducklington.net отримають одинакову кількість запитів направлених в блок appcluster.

В блоці server Nginx налаштований для прослуховування запитів на певну IP-адресу і порт (наприклад, 21.43.56.87 і 80), і відповідати на запити до доменів ducklington.org і www.ducklington.org.

Усі запити про виділення ресурсів у цьому домені (наприклад, /) будуть передані у http://appcluster, який описаний в директиві upstream.

Advanced Load Balancing

Nginx також надає можливість контролювати ресурси кластеру.
Найпростішою модифікацією є додавання директиви ip_hash до конфігурації блоку upstream.
Це призводить до того, що запити від IP-адреси будуть спрямовані на той самий back-end сервер, що і минулого разу.

Розглянемо наступний наприклад:
Уривок файлу: nginx.conf

upstream appcluster {
   ip_hash;
   server lollipop.ducklington.net:8801;
   server lollipop.ducklington.net:8802;
   server simons.ducklington.net:8801 down;
   server simons.ducklington.net:8802;
}

Тут, ip_hash спробуває забезпечити, щоб запити, що надходять з однієї IP-адреси залишаються прикріпленими до конкретних елементів кластеру.
Якщо якийсь сервер недоступний, Nginx перекине ці запити на альтернативний сервер з кластеру.

Якщо сервер повинен бути переведений в автономний режим протягом тривалого періоду часу, додайте аргумент down, як до запису для simons.ducklington.net: 8801, щоб запобігти появі коннектів до серверу, який не працює.

Ви також можете контролювати поведінку upstream кластера шляхом додавання одного або більше аргументів до кожного з елементів кластеру в блоці upstream:

* weight=[число] Встановлює вагу компонента кластера, за замовчуванням всі компоненти кластеру мають вагу 1.
Якщо ви хотіли б певним серверам, віддати більшу частку трафіку, потрібно встановити weight для цих сервери (компонентів).
* max_fails = [число] вказує число невдалих спроб спілкування з компонентом upstream до встановлення мітки “недіючий”.
Для запобігання встановлення мітки “недіючий” для конпоненту, навіть якщо він недоступний, встановіть це значення в 0.
Значення за замовчуванням для max_fails = 1.
*Fail_timeout = [час у секундах ] аргумент визначає проміжок часу, протягом якого max_fails число невдалих спроб повинно статися для того, щоб відзначити компонент як “недіючий”.

Зверніть увагу, сервери, які повертають код 404 розглядаються як працюючі, і це значення не впливає на тайм-аути для встановлених з’єднань проксі.

Пам’ятайте, що директива ip_hash не може бути використана з компонентами для яких визначені ці додаткові аргументи.

Розглянемо наступний приклад конфігурації upstream:

Уривок файлу: nginx.conf

upstream appcluster {
   server lollipop.ducklington.net:8801;
   server lollipop.ducklington.net:8802 weight=1;
   server lollipop.ducklington.net:8803 weight=2 max_fails=2;
   server lollipop.ducklington.net:8804 weight=2 max_fails=2 fail_timeout=20;
   server lollipop.ducklington.net:8805 weight=4;
   server lollipop.ducklington.net:8806 weight=4 fail_timeout=4;
   server lollipop.ducklington.net:8807 weight=2 fail_timeout=20;
}

У цьому прикладі, сім компонентів запущені на різних портах сервера lollipop.ducklington.net і входять в склад appcluster.

Компоненти, що працюють на портах 8801 і 8802 розглядаються однаково в Nginx, і мають weight=1.
Компоненти, що працюють на портах 8803, 8804 та 8807 отримують в два рази більше трафіку ніж перші два компоненти.
Компоненти на портах 8805 і 8806 будуть отримувати в чотири рази більше трафіку ніж 8801 і 8802 і в два рази більше трафіку ніж компоненти 8803, 8804 і 8807.

Компоненти на портах 8801, 8802, 8805, 8806 і 8807 можуть відмовитися від коннекту (refuse) лише один раз перед тим як будуть позначені як “недіючий”.
Компоненти 8803 і 8804 можуть потерпіти невдачу двічі, перш ніж вони позначаться як “недіючий”.

По замовчуванню, всі компоненти мають свої “лічильник відмов” які скидаються кожні 10 секунд, данне правило відноситься до компонентів 8801, 8802, 8803 і 8805.
Компоненти, 8804 і 8807 скидають свої “лічильник відмов” кожні 20 секунд, у той час як 8806 кожні 4 секунди.

Використовуючи ці аргументи, ви можете використовувати Nginx для управління поведінкою і розподіл навантаження на сервера кластеру.

Залишити відповідь