Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Stickiness и сессии
stickiness_sessions

Stickiness и сессии

Cookie-based sessions, source IP persistence, stick-tables

Stickiness и сессии в HAProxy

Session stickiness обеспечивает направление запросов от одного клиента на один и тот же backend сервер.

#Зачем нужна stickiness

Проблема:

Запрос 1 (login) → Server 1 → Сессия создана на Server 1
Запрос 2 (profile) → Server 2 → Server 2 не знает о сессии!

Решение — stickiness:

Запрос 1 (login) → Server 1 → Сессия + cookie=SRV1
Запрос 2 (profile) → cookie=SRV1 → Server 1 → Сессия найдена

#Cookie-based stickiness

#Basic cookie

backend web_servers balance roundrobin cookie SERVERID insert indirect nocache server web1 192.168.1.10:8080 check cookie web1 server web2 192.168.1.11:8080 check cookie web2 server web3 192.168.1.12:8080 check cookie web3

Как работает:

  1. Клиент делает первый запрос
  2. HAProxy выбирает сервер (например web1)
  3. HAProxy добавляет cookie: Set-Cookie: SERVERID=web1
  4. Следующие запросы с cookie SERVERID=web1 идут на web1

Параметры cookie:

  • insert — HAProxy добавляет cookie
  • indirect — cookie только от HAProxy к клиенту (backend не видит)
  • nocache — добавляет Cache-Control: no-cache для кэшей

#Cookie с prefix

backend web_servers cookie SERVERID insert prefix indirect nocache server web1 192.168.1.10:8080 check cookie web1 server web2 192.168.1.11:8080 check cookie web2

Поведение:

# Backend установил свою сессию:
Set-Cookie: SESSIONID=abc123

# HAProxy добавляет prefix:
Set-Cookie: SERVERIDweb1SESSIONID=abc123

Преимущество:

  • Не конфликтует с application cookies
  • Backend контролирует значение сессии

#Cookie с rewrite

backend web_servers cookie SERVERID rewrite indirect nocache server web1 192.168.1.10:8080 check cookie web1 server web2 192.168.1.11:8080 check cookie web2

Поведение:

  • rewrite — заменяет существующие cookie
  • Полезно если backend уже устанавливает cookie

#Source IP stickiness

backend web_servers balance source server web1 192.168.1.10:8080 check server web2 192.168.1.11:8080 check server web3 192.168.1.12:8080 check

Как работает:

  • Хэш от IP адреса клиента определяет сервер
  • Один IP → всегда один сервер

Преимущества:

  • ✅ Не требует cookies
  • ✅ Работает для любых клиентов

Недостатки:

  • ❌ Проблемы при NAT (один IP для многих клиентов)
  • ❌ Неравномерное распределение
  • ❌ Проблемы при изменении числа серверов

Когда использовать:

  • UDP трафик
  • Внутренние сервисы без cookies
  • Временное решение

#Stick-tables для stickiness

#Basic stick-table

backend web_servers stick-table type ip size 100k expire 1h # Сохраняем сервер для IP stick on src # Выбираем сервер по stick-table stick store-request src server web1 192.168.1.10:8080 check server web2 192.168.1.11:8080 check

Как работает:

  1. Первый запрос от IP → выбирается сервер (например web1)
  2. HAProxy сохраняет в stick-table: IP → web1
  3. Следующие запросы от того же IP → web1 из таблицы
  4. Через 1 час запись истекает

#Stick-table с cookie

backend web_servers stick-table type string size 100k expire 1h store server_id # Сохраняем сервер для cookie stick on hdr(cookie) -m str SESSIONID server web1 192.168.1.10:8080 check server web2 192.168.1.11:8080 check

Параметры:

  • type string — ключ строка (значение cookie)
  • store server_id — хранит ID сервера

#Stick-table с fallback

backend web_servers stick-table type ip size 100k expire 1h stick on src stick store-request src # Если сервер DOWN, выбрать новый stick store-request src if !SERVER_DOWN server web1 192.168.1.10:8080 check server web2 192.168.1.11:8080 check

#URL Parameter stickiness

backend api_servers balance url_param session_id server api1 192.168.1.10:8080 check server api2 192.168.1.11:8080 check

Как работает:

GET /api/data?session_id=abc123 → hash → web2
GET /api/data?session_id=abc123 → hash → web2
GET /api/data?session_id=xyz789 → hash → web1

Когда использовать:

  • Legacy приложения с сессией в URL
  • API с session token в query string
  • Когда cookies недоступны

#Header-based stickiness

backend api_servers balance hdr(X-User-ID) server api1 192.168.1.10:8080 check server api2 192.168.1.11:8080 check

Как работает:

X-User-ID: 12345 → hash → web2
X-User-ID: 12345 → hash → web2
X-User-ID: 67890 → hash → web1

Когда использовать:

  • Микросервисы с user ID в header
  • JWT токены
  • API key аутентификация

#SSL Session ID stickiness

backend secure_servers balance ssl_fc_session_id server web1 192.168.1.10:8443 check ssl server web2 192.168.1.11:8443 check ssl

Как работает:

  • SSL Session ID используется как ключ
  • Один SSL session → один сервер

Преимущества:

  • ✅ Работает на уровне SSL
  • ✅ Прозрачно для приложения

Недостатки:

  • ❌ Только для HTTPS
  • ❌ Проблемы при SSL termination на HAProxy

#Persistence Timeout

backend web_servers cookie SERVERID insert indirect nocache stick-table type ip size 100k expire 2h stick on src stick store-request src server web1 192.168.1.10:8080 check server web2 192.168.1.11:8080 check

Параметры:

  • expire 2h — сессия действительна 2 часа
  • После истечения — новый сервер

#Dynamic Stickiness с Stats Socket

# Показать stick-table echo "show table web_servers" | socat /var/run/haproxy/admin.sock stdio # Удалить запись echo "clear table web_servers key ip 192.168.1.100" | socat /var/run/haproxy/admin.sock stdio # Показать сервер для IP echo "show table web_servers type ip key 192.168.1.100" | socat /var/run/haproxy/admin.sock stdio

#Stickiness для WebSocket

frontend ws_front bind *:80 acl is_websocket hdr(Upgrade) -i websocket use_backend ws_servers if is_websocket backend ws_servers balance source timeout tunnel 1h server ws1 192.168.1.10:8080 check server ws2 192.168.1.11:8080 check

Важно:

  • WebSocket требует долгой stickiness
  • timeout tunnel 1h для долгоживущих соединений
  • balance source для IP-based stickiness

#Full Example: Production Stickiness

backend web_servers # Балансировка balance roundrobin # Cookie-based stickiness cookie SERVERID insert indirect nocache maxlife 8h # Stick-table для fallback stick-table type ip size 100k expire 2h # Сохраняем IP → сервер stick on src # Серверы server web1 192.168.1.10:8080 check cookie web1 weight 10 server web2 192.168.1.11:8080 check cookie web2 weight 10 server web3 192.168.1.12:8080 check cookie web3 weight 5 backup

Параметры:

  • maxlife 8h — максимальное время жизни cookie
  • weight — приоритет серверов
  • backup — резервный сервер

#Troubleshooting Stickiness

#Проверка cookie

curl -v http://example.com/ 2>&1 | grep Set-Cookie # Set-Cookie: SERVERID=web1

#Проверка stick-table

echo "show table web_servers" | socat /var/run/haproxy/admin.sock stdio

#Логи stickiness

# Логирование выбора сервера log-format "%ci:%cp %ft %b/%s %ST %B %{+Q}r cookie=%[res.cooki(SERVERID)]"

#Best Practices

#Cookie name

# Хорошо (уникальное имя) cookie SERVERID insert # Плохо (может конфликтовать) cookie SESSIONID insert

#Expiration

# Баланс между стабильностью и гибкостью cookie SERVERID insert indirect nocache maxlife 4h stick-table type ip size 100k expire 2h

#Fallback

# Всегда имейте fallback на случай если сервер DOWN stick store-request src if !SERVER_DOWN

Далее: HTTP rewrite и модификация