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

Архитектура бэкенда

Пулинг: чтение кода и конфига

Суть Читай реальный конфиг pool, код хендлера и строку лога Postgres, предсказывай отказ и выбирай фикс с наибольшим рычагом — формула размера, leak, idle-in-transaction и конфиг таймаутов.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 14 min

Инциденты с pool диагностируются в конфиг-файлах, коде хендлеров и логе базы — не в абстракции. Прочитай каждый сниппет, предскажи отказ, который он даёт под нагрузкой, и выбери фикс, который senior-инженер сделает первым.

Цель

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

Сниппет 1 — размер pool

# Postgres на 4 vCPU, один SSD. Сервис держит ~2000 req/s.
# Запаниковавший инженер выставил это после алерта "DB is the bottleneck":
spring.datasource.hikari.maximum-pool-size: 200
spring.datasource.hikari.minimum-idle: 200
Викторина

На этой 4-vCPU, одно-SSD базе, каким на самом деле должен быть maximum-pool-size и почему 200 вредны?

Сниппет 2 — хендлер

async function getUser(id) {
  const conn = await pool.acquire();
  const rows = await conn.query("SELECT * FROM users WHERE id = $1", [id]);
  conn.release();           // возвращает соединение в pool
  return rows[0];
}
Викторина

Этот хендлер работает в тестах, но pool осушается до пустого за часы в проде, чинится только рестартом. В чём дефект и фикс?

Сниппет 3 — строка лога Postgres

LOG:  duration: 612000.244 ms  state: idle in transaction
DETAIL:  process 48213 has been idle in transaction for 00:10:12
HINT:  Sessions idle in transaction hold their connection and any locks.
Викторина

Несколько backend'ов показывают 'idle in transaction' минутами, и pool продолжает истощаться. Что происходит и какая защита верна?

Сниппет 4 — конфиг таймаутов

spring.datasource.hikari.connection-timeout: 30000   # 30 с, дефолт
spring.datasource.hikari.max-lifetime: 28800000      # 8 ч
# Бэкенд MySQL имеет wait_timeout = 28800 (8 ч, дефолт)
Викторина

В этом конфиге прячутся две проблемы, которые укусят при медленной зависимости и после простоев. Какой фикс корректно адресует обе?

Итог

Каждый инцидент с пулингом читается в конфиге, коде и логах: pool, заданный в 200 на 4 ядрах, — это contention, а не конкурентность (эвристика (cores x 2) + spindles ставит его около 9); release() вне try/finally течёт на error-пути и осушает pool за часы; ‘idle in transaction’ в логе значит соединение, придержанное внутри открытой транзакции через несвязанную работу, держащее локи; а 30-секундный acquisition timeout плюс max-lifetime, не подрезающий DB wait_timeout, — ловушка starvation-и-stale-сокетов. Диагностируй по уликам, чини структурно (правильный размер, гарантированный return, узкие транзакции, ограниченные ожидания), затем перемеряй.

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

Trademarks belong to their respective owners. Editorial reference only.