Я создал Flask
WSGI-приложение, которое использует gunicorn
в качестве WSGI-сервера, для БД оно использует расширение от PostgreSQL
до Flask SQLAlchemy
. Все это размещено на Heroku
.
конфигурация gunicorn
- количество рабочих: 2;
- количество рабочих соединений: 1024;
- количество потоков: 1;
- рабочий класс: gevent.
Heroku PostgreSQL конфигурация
- максимальное количество соединений: 20.
Для всего остального используется конфигурация по умолчанию.
Я получаю эту ошибку: sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) FATAL: too many connections for role <id>
. Очевидно, превышено допустимое количество подключений к БД.
Я пытался это исправить:
- для SQLAlchemy установить
poolclass
в NullPool
; - для SQLAlchmey установить
pool_recycle
на 2. Количество соединений остается неизменным даже после более чем 2 секунд; session.close()
с engine.dispose()
; - количество рабочих - 2, количество рабочих соединений - 9;
- количество рабочих - 1, количество рабочих соединений - 18;
- количество рабочих - 1, количество рабочих соединений - 10, SQLAlchemy
max_overflow = 0
, SQLALchmey pool_size = 10
(я получаю эту ошибку: sqlalchemy.exc.TimeoutError: QueuePool limit of size 10 overflow 0 reached, connection timed out, timeout 30
).
Ничего из этого не работает. Я все еще получаю эту ошибку даже при минимальной конфигурации Gunicorn (1 рабочий с 18 подключениями). Я действительно начал не понимать, что на самом деле происходит.
Я думал, что это работает так: у каждого работника есть свой экземпляр движка, и у каждого движка свой размер пула. Итак, если есть 2 рабочих с конфигурацией двигателя по умолчанию (размер пула 5), то у нас будет 2 * 5 = 10 максимальных подключений к БД. Но похоже, что это действительно не так.
Вопросы
- как исправить эту ошибку?
- как
SQLAlchemy
объединение работает с gevent
работниками? то есть, как я могу подсчитать максимальное количество соединений с БД? - как мне правильно настроить его так, чтобы он работал как положено?
Извините за слишком много вопросов, но это действительно расстраивает меня.