awesome-everything EN
↑ Обратно к восхождению

Сети и протоколы

Proxy и load balancing: чтение конфигов и кода

Суть Читайте реальные конфиги LB, сниппет балансировки, заголовок PROXY protocol и обработчик graceful shutdown — затем выбирайте поведение или исправление с наибольшим рычагом.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 14 min

Поведение LB решается в конфигах и обработчиках завершения, а не на диаграммах. Прочитайте каждый сниппет, предскажите его поведение под нагрузкой и выберите исправление, которое senior-инженер сделает первым.

Цель

Отработайте цикл, который вы запускаете на каждом инциденте с LB: прочитать конфиг upstream или обработчик, предсказать режим отказа и взяться за изменение, которое действительно его чинит.

Сниппет 1 — блок upstream в nginx

upstream api {
    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
    server 10.0.0.3:8080;
}

server {
    location / {
        proxy_pass http://api;
    }
}
Викторина

Стоимость запросов сильно разнится, и один backend периодически уходит в паузу GC. С этим default-конфигом что произойдёт и какое однострочное изменение даёт наибольший рычаг?

Сниппет 2 — power-of-two-choices вручную

import random

def pick_backend(backends):
    a, b = random.sample(backends, 2)        # два разных, равномерно случайно
    return a if a.active_conns <= b.active_conns else b
Викторина

Это ядро power-of-two-choices. Почему выборка ровно двух — а не скан всех N ради истинного минимума — важна в продакшене?

Сниппет 3 — заголовок PROXY protocol

PROXY TCP4 203.0.113.195 198.51.100.7 56324 443\r\n
GET /orders HTTP/1.1
Host: shop.example.com
Викторина

Backend на чистом TCP (не HTTP) нуждается в реальном IP клиента для rate limiting. LB добавляет строку выше. Какое утверждение верно?

Сниппет 4 — graceful shutdown по SIGTERM

func main() {
    srv := &http.Server{Addr: ":8080", Handler: mux}
    go srv.ListenAndServe()

    <-sigterm                                  // LB пометил нас как draining
    ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second)
    defer cancel()
    srv.Shutdown(ctx)                          // перестать принимать, дослужить in-flight
}
Викторина

Этот обработчик кооперируется с connection draining. Что делает srv.Shutdown и какой один продакшен-пробел тут важно отслеживать?

Итог

Проблемы LB живут в конфигах и обработчиках. Default в nginx — round-robin, поэтому load-aware политика вроде least_conn (или P2C в upstream) — это исправление для слепого к нагрузке пула. Power-of-two-choices — это две случайные выборки плюс одно сравнение: O(1) и рассинхронизирует стадо, а не просто более дешёвый least-connections. Преамбула PROXY protocol восстанавливает IP клиента для любого протокола транспортного уровня, но ей нужно доверять только с известных IP proxy. А graceful shutdown (закрыть слушатель, дослужить in-flight, таймаут) работает лишь когда окно draining приложения и drain timeout у LB рассчитаны вместе на самое долгоживущее соединение.

Продолжить восхождение ↑Proxy и load balancing: пережить падающий backend
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.