Pull to refresh

Comments 6

UFO just landed and posted this here

если вдруг есть планы перевести это на английский — будет супер полезно!

Спасибо за статью, очень круто. Немного оффтоп, но не могли бы подробнее рассказать про балансировку gRPC? Она происходит на gRPC клиенте (в статье вроде было про service discovery)? Или все же есть промежуточный http2 балансировщик? Если да, то какой?

Нам от gRPC балансировки в первую очередь нужно, чтобы клиент выбирал живой хост из списка. В таком виде она работает между loadbalancer-controller и loadbalancer-node. Последняя подписывается на изменения состава балансеров, и там как раз мы и используем gRPC балансировку. Пакет memberlist (используется в consul реализует в себе логику service discovery: в ней есть встроенные механизмы healthcheck'ов и распространение их результатов по gossip протоколу. Мы у себя их подружили в таком виде, что memberlist сообщает об изменении списка живых хостов, и мы меняем список хостов в группе gRPC балансировки.


Memberlist мы немного дописывали и возвращали код в open source, но пока пользуемся своим форком. Фактически, проблема только одна в указанном PR: мы наблюдали высокое потребление памяти, но в остальном всё работает хорошо.


В других местах мы просто используем memberlist, потому что дальше у нас возникает шардирование. Цели healthcheck'ов (rip'ы) шардированы по healthcheck-controller'ам, так, что за одну цель отвечает один контроллер (он агрегирует результаты проверок, которые сообщают healthcheck-node). Поэтому loadbalancer-controller'ы подписываются на результаты проверок целей, подключаясь к конкретному healthcheck-controller'у, ответственному за эту цель, так что тут нам gRPC балансировка мешает. При изменении состава healthcheck controller'ов memberlist сообщает нам об этом и мы перераспределяем цели по новому списку healthcheck-controller'ов. Кстати, тут мы также пользуемся консистентным хэшированием примерно по тем же соображениям: легче масштабироваться горизонтально, так как не требуется синхронизация состояний между loadbalancer-controller'ами, и перемещению подвергается небольшая часть целей.


Между healthcheck-controller'ами и healthcheck-node примерно такая же история. Каждая проверка выполняется минимум тремя healthcheck-node'ами, но проверки шардированы между всем множеством нод (условно, если у нас шесть healthcheck-node, то проверка П будет выполняться на трёх из них). Шардирование так же выполняется консистентным хэшированием, и healthcheck-node знают, куда именно нужно отправлять результат, так что тут gRPC балансировка тоже не нужна.


Выше описана клиентская балансировка (у нас round-robin, но, опять же, нас скорее интересует исключение мёртвых хостов, чем непосредственно балансировка, так как в большинстве случаев мы работаем с gRPC stream'ами). Для серверной баланировки gRPC я бы рекомендовал попробовать envoy (например, вот статья с историей успеха), там реализовано несколько алгоритмов балансировки, в том числе и динамические.

Спасибо за ответ. Согласен, такая балансировка это по факту отсутствие балансировки (регулируется только живость хостов, не нагрузка), т.к. каждый клиент сам делает свой round-robin, а не один сквозной на всех :) в случае со стримами так вообще беда. Или если клиентов много, то еще и гигантское количество TCP соединений на каждом gRPC сервере. Статья выглядит годной

@serejkus Спасибо за пост.
Можно ли извлекать информацию из сообщения ClientHello без терминирования SSL/TLS в NLB?
Это реализовано в nginx с помощью модуля http://nginx.org/ru/docs/stream/ngx_stream_ssl_preread_module.html

Пример https://gist.github.com/kekru/c09dbab5e78bf76402966b13fa72b9d2

Sign up to leave a comment.