data-infra
Словарь ↗Пулинг соединений (Connection Pooling)
Пулинг соединений (connection pooling) — техника, при которой фиксированный набор заранее установленных соединений с базой данных остаётся открытым и совместно используется для входящих запросов, вместо того чтобы каждый запрос открывал совершенно новое соединение с базой данных и закрывал его по завершении. Открытие соединения с базой данных дорого по сравнению с фактическим запросом, который оно выполнит, — оно включает TCP-рукопожатие, аутентификацию и (конкретно для Postgres) запуск отдельного бэкенд-процесса на соединение, — поэтому делать это при каждом запросе является значительным, но избегаемым налогом на задержку и ресурсы сервера. Почему это важно для разработчиков AI/SaaS: это становится острой, ломающей продукт проблемой именно в serverless- и edge-развёртываниях (Vercel, AWS Lambda, Cloudflare Workers), которые теперь стали моделью развёртывания по умолчанию для огромной доли новых AI-продуктов. Serverless-функции постоянно запускаются и завершаются, и без пулинга каждый вызов, открывающий собственное соединение с базой данных, может исчерпать довольно низкий лимит соединений Postgres по умолчанию (обычно 100) за секунды под реальной нагрузкой, вызывая ошибки «слишком много соединений», которые обрушивают всё приложение — режим отказа, который не проявляется в локальной разработке и появляется только когда реальные одновременные пользователи попадают в production. Как это работает: пулер соединений находится между приложением и базой данных, поддерживая набор уже открытых соединений и раздавая их запросам по мере необходимости, возвращая их обратно в пул по завершении запроса вместо закрытия. Пулы на уровне приложения (встроенные в большинство драйверов баз данных и ORM) работают внутри одного долгоживущего серверного процесса; но serverless-функции не имеют состояния и живут недолго, поэтому им нужен внешний пулер вроде PgBouncer или его управляемый эквивалент (встроенный пулер Supabase, пулинг соединений Neon, прокси PlanetScale), который существует независимо от любого отдельного вызова функции и мультиплексирует множество эфемерных serverless-соединений в небольшое число реальных соединений с базой данных. Практический пример: AI SaaS, развёрнутый на serverless-функциях Vercel, начинает видеть периодические ошибки 500 под нагрузкой — логи Postgres показывают `FATAL: too many connections`, потому что каждый из сотен одновременных вызовов Lambda открыл собственное прямое соединение с базой данных. Решение: направить URL базы данных приложения через PgBouncer в режиме пулинга транзакций, который мультиплексирует эти сотни эфемерных serverless-соединений в стабильный пул из 20 реальных бэкенд-соединений — устраняя ошибки исчерпания соединений без изменения ни единой строки кода запросов. Решение также немного сокращает среднюю задержку запросов, поскольку повторное использование уже открытого пулированного соединения избегает накладных расходов на рукопожатие, которые ранее оплачивались при каждом отдельном вызове — редкий случай, когда исправление проблемы надёжности и улучшение производительности происходят от одного и того же изменения.
Похожие термины