Назад | Перейти на главную страницу

DNS Failover с несколькими балансировщиками нагрузки Nginx

Наше приложение размещено на EC2, однако из-за характера приложения оно требует чрезвычайно высокой доступности. У нас есть изображение приложения, работающего на Linode в качестве аварийного.

Однако переключение DNS на Linode займет некоторое время. Мы разработали стратегию минимизации этого времени простоя, но я хотел бы получить несколько советов о том, как ее лучше всего реализовать.

Приложение представляет собой приложение ROR. Мы запускаем 6 внешних узлов на EC2 и используем Nginx в качестве балансировщика нагрузки с proxy_pass.

Однако наш балансировщик нагрузки на Linode балансирует не по узлам Linode, а по узлам EC2. Таким образом, у нас есть IP-адрес нашего Linode LB в нашей записи DNS. Поэтому, когда клиент подключается, циклический перебор DNS выполняется либо с EC2, либо с Linode LB. Выбранный LB затем перенаправит запрос на один из узлов на EC2. В случае сбоя EC2 мы просто изменим конфигурацию Linode LB, чтобы сбалансировать его собственный узел (плюс другие вещи, такие как переключение БД и т. Д., И т. Д.).

Я знаю, что это плохо для производительности, но для нас важнее надежность.

К слову, у нас возникают вопросы, когда по какой-либо причине Linode LB не может подключиться к EC2. В этом случае Nginx вернет ошибку 502 Bad Gateway, которая не заставит клиента использовать аварийное переключение DNS.

Мы надеемся найти способ заставить клиента использовать резервный DNS-сервер при возникновении такой ситуации. Есть способ сделать это? Желательно с Nginx, но будут рассмотрены другие решения, если он этого не поддерживает.

Спасибо!

Мне нравится этот подход, он мой самый любимый, и я куплю вам пива, если вы когда-нибудь будете в Сан-Франциско!

Два ответа, сначала на вашу проблему 502, вы должны добавить это в свой nginx, поэтому, если есть хотя бы некоторые подходящие узлы, nginx повторит попытку (по умолчанию на 502 он просто сдается):

http://wiki.nginx.org/HttpProxyModule#proxy_next_upstream

proxy_next_upstream 

syntax: proxy_next_upstream [error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off];

Во-вторых, для вашего «возврата к DNS» вам нужно немного изменить подход. Для этих настроек то, что я обычно делал, - это перетаскивание DNS полностью обратно к самим узлам приложения, что тестирует подключение на всем пути через балансировщик нагрузки и до конечного узла. В качестве бонуса вы можете интегрировать DNS со своим приложением и отключить DNS-сервер, если приложение не работает. Идея здесь состоит в том, чтобы DNS-запрос клиентов «проверял», работает ли весь путь, а не только подключение к LB. Очевидно, вы не можете использовать для этого NGINX, я использовал для этого правила pf, вы можете сделать то же самое в iptables. Где вы просто запрашиваете циклический перебор к внутренним узлам и запускаете привязку на своих внутренних серверах. Идея состоит в том, чтобы убедиться, что у вас есть несколько записей NS, по одной на каждый имеющийся у вас LB. Клиент позаботится о тестировании каждой записи NS. При тестировании, которое я проводил, среднее время переключения при отказе составляет 2 секунды, и это работало для 99% операционных систем, которые мы рассматривали. Дайте мне знать, если в этом есть смысл. Это будет работать лучше, чем любой сценарий, который пытается восстановить после того, как клиент уже сделал первый запрос TCP.

С помощью этого решения я создал сайты, которые поддерживают 100% доступность согласно данным мониторинга Gomez и Keynote. Как вы уже упоминали, это может привести к некоторому снижению начальной производительности при поиске в DNS, но сайт всегда работает, и клиентам это нравится (как и мой пейджер).