haproxy на клиентской стороне

26 марта 2019

В настоящее время многие сервисы поддерживают отказоустойчивость из коробки, т.е. могут быть установлены на несколько узлов и (а) сохранять работоспособность при выходе из строя части из них, а также (б) распределять нагрузку между собой, т.е. предоставлять HA/LB — High Availibility и Load Balancing.

Некоторые известные примеры: LDAP, ElasticSearch, Ceph, MySQL (шутка) и т.д.

Проблема заключается в том, что клиентская часть не всегда знает и поддерживает кластерные возможности серверной части. Например, связь с ElastisSearch производится по протоколу HTTP. Если узел кластера, с которым связывается клиентское приложение, становится нерабочим, приложение должно самостоятельно принять решение, что надо обращаться к другому узлу кластера, т.е. использовать другой URL.

Решить данную проблему можно несколькими способами. Перечислим наиболее известные из них:

  • балансировка по IP-адресу;
  • DNS-балансировка;
  • BGP anycast;
  • Frontend — все запросы приходят на приложение-балансировщик (в зависимости от протокола — nginx, haproxy, mysql router и т.д.), которое передаёт их на исправные узлы.

Каждый из этих методов имеет свои недостатки:

  • IP-балансировка требует, чтобы серверы находились в одной подсети.
  • DNS-балансировка практически не используется, т.к. имеет недопустимо большое время задержки, потому что DNS-записи кэшируются на срок от нескольких минут до суток.
  • BGP anycast в публичной сети требует анонсировать блок не меньше /24. Мы рассматриваем случай, когда и сервисы, и клиентская часть являются частью одного распределённого приложения, поэтому допустимо использовать для их связи приватные диапазоны ASnums и IP-адресов, но если сервисы находятся в разных точках сети, то такой BGP сможет работать только поверх VPN. Вряд ли надо пояснять, что в силу громоздкости подобная конструкция способна стать как решением существующих проблем, так и источником новых.
  • Frontend является единой точкой отказа, а его пропускная способность — потенциальным узким местом.

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

На эту роль идеально подходит haproxy — производительный, относительно компактный, с простым файлом настроек, и с возможностью менять настройки на лету.

Доступность сервисов haproxy умеет проверять на двух уровнях:

  • сетевом — отвечает ли TCP-порт на запрос соединения;
  • прикладном — в настоящий момент поддерживаются HTTP, LDAP, MySQL, PostgreSQL, Redis и SMTP.

Например, если приложение должно работать с кластерами ElasticSearch и MySQL, то конфигурация haproxy может выглядеть примерно так:

listen mysql
    bind 127.0.0.1:3306
    mode tcp
    balance roundrobin
    option mysql-check user haproxy_check
    server mysql-cluster-node-1 10.0.0.1:3306 check
    server mysql-cluster-node-2 10.0.0.2:3306 check

listen elastic
    bind 127.0.0.1:9200
    mode http
    balance roundrobin
    option forwardfor
    option httpclose
    option httpchk
    http-check expect status 200
    server es-cluster-node-1 10.0.0.101:9200 check
    server es-cluster-node-2 10.0.0.102:9200 check

listen 0.0.0.0:8080
    mode http
    stats enable
    stats uri /haproxy_stats
    stats auth haproxy_admin:VerySecretPassword

Дополнительным достоинством данной схемы является упрощение установки приложений — теперь от них требуется подключаться к сервисам по адресу 127.0.0.1, т.е. достаточно один раз указать этот адрес при разработке в настройках по умолчанию. За знание фактических адресов сервисов будет отвечать haproxy, настроенный под конкретную конфигурацию кластеров.

Если распределённая система не планирует разрастаться до таких размеров, при которых становится оправданным внедрение Consul или его аналогов — предложенный здесь вариант является приемлемым сочетанием простоты, надёжности, производительности и гибкости.



← Назад в Блог

Подпишитесь на новые статьи: