База данных уровня хобби PostgreSQL содержит не более 20 соединений, и поэтому я реализовал небольшой триггер, чтобы закрывать соединения с базой данных, как только будет достигнута квота соединения.
установленная мной квота равна 10, и на локальной машине, которая heroku local
работает отлично, но на сервере Heroku он не закрывает используемые соединения. Стоит упомянуть, что я реализовал страницу stats
, содержащую количество открытых соединений (используя sql.DB.Stats().InUse
), используемое *sql.DB
приложения (которое реализовано как одиночный), и на странице показано количество открытых соединений после однократное использование, которое меньше, чем показано на странице состояния базы данных Heroku.
Вышеупомянутый триггер применяется всякий раз, когда приложение запрашивает соединение, и реализуется следующим образом:
func GetConnection() *sql.Conn {
// The connect just opens a connection with the database returning a valid *sql.DB
if Database == nil {
Connect()
}
if Database.Stats().InUse >= 10 {
Database.Close()
// Seems like Java but I just wanted to be sure on Heroku
Database = nil
Connect()
}
ctx, _ := context.WithTimeout(context.Background(), time.Second*10)
conn, err := Database.Conn(ctx)
if err != nil {
log.Printf("Couldn't get a connection from the pool. Reason %v", err)
}
return conn
}
Как вы можете видеть, я даже реализовал контекст с тайм-аутом в 10 секунд для автоматической отмены установленного соединения, но, похоже, это не сработало.
- Я пытался использовать
pgbouncer
, но как на моей локальной машине, так и на сервере Heroku, похоже, он тоже не работает. - Другая вещь, которую я попробовал, -
defer c.Close()
соединение, полученное от GetConnection()
, но это останавливает приложение. - Пытался использовать
sql.DB.SetMaxOpenConns(...)
, но это не работает так, как объяснялось в комментариях.