- PVSM.RU - https://www.pvsm.ru -
Каждого представляет Джеральд Брофловски, адвокат из Саус Парка, который рассчитывает получить неплохую комиссию. Противоположную сторону каждого представляет… Джеральд Брофловски! Кажется, папу Кайла ждут нехилые бабосы независимо от исхода дела.
South Park, серия 306, «Панда—сексуальное домогательство»
Не так давно наши коллеги рассказали на конференции HighLoad++ [1] о решении задачи балансировки нагрузки в облаках Google и Amazon, а также DNS-балансировки с использованием сервиса gdnsd. Это отличное введение в тему, с которым стоит познакомиться всем, кого жизнь уже заставила завести несколько фронтендов. И практическое руководство, если вы вынуждены иметь дело с облачным
К счастью, бывают случаи, когда вы можете позволить себе удовольствие работать с реальным оборудованием, а не с облаками. Автор этих строк обожает реальное оборудование и готов часами рассказывать про его плюсы:
Многие dedicated-провайдеры научились объединять серверы в виртуальные сети, и расширение ферм в них не представляет проблемы. Популярное исключение — Hetzner, где по-прежнему нужно резервировать юниты и планировать место, но я надеюсь, что он тоже разродится умной коммутацией. А вот с балансировкой дела обстоят хуже.
Там, где вообще есть смысл обсуждать с провайдером балансировку, вам предложат современного потомка чего-то такого:
Железо это штучное, стоить оно будет, разумеется, оскорбительных денег, а для конфигурирования требовать специальных знаний.
И тут самое время вспомнить, что…
Ваши фермы наверняка уже работают с применением одного из средств автоматизации, а это значит, что массовые изменения дёшевы. А в качестве HTTP-фронтенда с большой вероятностью используется nginx на тех же серверах, что и обслуживают приложение. Это позволяет легко построить схему балансировки «каждый с каждым» — каждый сервер будет балансером, и он же захостит приложение, отвечающее на запрос.
Конфигурируем пул серверов в gdnsd:
; Проверяем отдельно написанной командой, жив ли
; сервер с таким IP-адресом
service_types => {
adserver => {
plugin => extmon,
cmd => ["/usr/local/bin/check-adserver-node-for-gdnsd", "%%IPADDR%%"]
down_thresh => 4, ; Не ответил 4 раза на тест? Этот сервер лежит.
ok_thresh => 1, ; Хоть раз ответил нормально? Жив!
interval => 20, ; Проверяем каждые 20 секунд
timeout => 5, ; Тупку более 5 секунд считаем отсутствием ответа
} ; adserver
} ; service_types
plugins => {
multifo => {
; Если живы менее 1/3 хостов, то DNS будет возвращать весь список
; серверов, потому что явно происхоит что-то не то — например, общая
; перегрузка приложения, и отключение «сломанных» только усугубляет
; ситуацию
up_thresh => 0.3,
adserver-eu => {
service_types => adserver,
www1-de => 192.168.93.1,
www2-de => 192.168.93.2,
www3-de => 192.168.93.3,
www4-de => 192.168.93.4,
www5-de => 192.168.93.5,
} ; adserver-eu
} ; multifo
} ; plugins
Используем полученную конфигурацию в файле DNS-зоны:
eu.adserver.sample. 60 DYNA multifo!adserver-eu
Делаем для nginx пул серверов и раскатываем конфигурацию по ферме:
upstream adserver-eu {
server localhost:8080 max_fails=5 fail_timeout=5s;
server www1-de.adserver.sample:8080 max_fails=5 fail_timeout=5s;
server www2-de.adserver.sample:8080 max_fails=5 fail_timeout=5s;
server www3-de.adserver.sample:8080 max_fails=5 fail_timeout=5s;
server www4-de.adserver.sample:8080 max_fails=5 fail_timeout=5s;
server www5-de.adserver.sample:8080 max_fails=5 fail_timeout=5s;
keepalive 1000;
}
Если в ротации больше 25 серверов, не забудьте разбить их на группы по 25 штук под единым именем [4], и динамически выбирать в gdnsd синонимы (DYNC) вместо A-записей.
Список серверов при желании можно заполнять автоматически по данным gdnsd или системы автоматизации. Например, у нас в компании используется puppet, и специальный крон-скрипт поддерживает в актуальном состоянии списки серверов разных типов, зарегистрированных на пуппетмастере. Строка с localhost защищает от ситуации, когда список окажется пустым из-за ошибки — в этом случае каждый nginx будет обслуживать только свой фронтенд, и катастрофы не произойдёт.
Итак, что получилось:
За бесплатную балансировку нужно платить, и жертвой являются sticky-сессии. Тем не менее, бесплатный вариант nginx предлагает балансировку по хешам IP [5], а современные NoSQL-базы, такие как Aerospike, могут быть использованы как надёжное общее хранилище сессий с быстрым временем ответа, которое вы можете использовать в своих приложениях. Наконец, можно, хоть это и непатриотично, перейти на HAProxy, который умеет маршрутизовать пользователей на нескольких балансерах по единому правилу [6]. В общем, когда нам понадобятся sticky-сессии, мы будем бороться за них имеющимися средствами.
Сейчас каждый из наших 20-ядерных серверов обрабатывает до 15 000 запросов в секунду, что близко к практическому потолку нашего Java-приложения. По всем кластерам мы балансируем и обрабатываем в пике больше полумиллиона запросов в секунду, 5 Гбит/с входящего и 4 Гбит/с исходящего трафика, за исключением CDN. Да, специфика DSP — это превышение входящего над исходящим, аукционных предложений значительно больше, чем содержательных ответов на них.
Автор статьи — igors [7]
Автор: miss_dy
Источник [8]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/nginx/255629
Ссылки в тексте:
[1] рассказали на конференции HighLoad++: https://habrahabr.ru/post/321560/
[2] хостингом: https://www.reg.ru/?rlink=reflink-717
[3] занимает три десятка страниц A4: http://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html
[4] не забудьте разбить их на группы по 25 штук под единым именем: http://stackoverflow.com/questions/6794926/how-many-a-records-can-fit-in-a-single-dns-response
[5] балансировку по хешам IP: http://nginx.org/en/docs/http/load_balancing.html#nginx_load_balancing_with_ip_hash
[6] умеет маршрутизовать пользователей на нескольких балансерах по единому правилу: http://blog.haproxy.com/2012/03/29/load-balancing-affinity-persistence-sticky-sessions-what-you-need-to-know/
[7] igors: https://habrahabr.ru/users/igors/
[8] Источник: https://habrahabr.ru/post/329012/
Нажмите здесь для печати.