Архитектура бэкенда
Пулинг: тест с множественным выбором
Шесть вопросов, пронизывающих весь юнит. Каждый отражает решение, которое ты принимаешь в реальном инциденте с пулингом — не определение для пересказа, а компромисс, который надо взвесить, когда pool пуст, течёт или сходится (fan-in) в одну общую базу.
Убедись, что можешь связать pool size, acquisition timeout, жизненный цикл соединения, leaks и распределённый fan-in — синтез, к которому вели отдельные уроки.
Команда делает базу узким местом и поднимает pool с 20 до 100 на 8-ядерном Postgres, ожидая примерно 5x пропускной способности. Пропускная способность падает, задержка растёт. Почему?
Запрос вниз по стеку, обычно занимающий 5 мс, замедляется до 500 мс; за секунды весь веб-слой перестаёт принимать запросы, хотя база всё ещё жива. Каков механизм и первый конфиг-фикс?
После ночного затишья первые утренние запросы падают с 'connection reset by peer'; ничего не деплоили, база здорова. Что произошло и какой контроль — корневая защита?
Сервис таймаутит на acquisition соединений после часов работы; рестарт чинит на несколько часов, затем повторяется, и всё это при нормальном трафике. Почему увеличение pool — неверный фикс?
Хендлер берёт соединение из pool, затем await'ит медленный внешний HTTP-вызов до своего запроса. Ничего не течёт — try/finally всегда освобождает. Почему это всё равно истощает pool под нагрузкой?
Сервис, здоровый на одном инстансе (pool 20), начинает кидать 'FATAL: sorry, too many clients already' после автоскейла до 50 инстансов. Утечек pool нет. Каков фикс и его главная цена корректности?
Сквозная линия юнита — одна цепочка: pool амортизирует setup соединения и ограничивает конкурентность, поэтому его размер мал и выведен из ядер (а не угадан большим); когда он пустеет, acquisition timeout решает, упадёшь ли ты быстро или заморишь веб-слой; удерживаемые им соединения протухают и должны ротироваться по maxLifetime и валидироваться on borrow; самый частый отказ — leak (или hoarding через await), который больший pool лишь оттягивает и прячет; а на масштабе многие pool сходятся в один max_connections, вынуждая transaction-pooling мультиплексор, торгующий состоянием сессии. Каждый ответ возвращается к одной дисциплине — ограничивай ресурс осознанно (size, wait, age, return, fan-in), а не позволяй внешней системе ограничить его за тебя в худший момент.