Я реализую код, где мне нужно выполнять несколько действий с фиксированными интервалами.
Немногие из них связаны с извлечением данных из базы данных mysql.
Чтобы запланировать эти действия с фиксированным интервалом, я использую gocron. Он работает достаточно хорошо.
Для базы данных на данный момент я создаю экземпляр в начале основной программы и передаю его подпрограмм. Я использую https://github.com/jmoiron/sqlx для работы с БД.
Поток кода:
i- инициализировать ресурсы. Например, db = sql.Open; поместите DB в общую структуру, чтобы перейти ко всей подпрограмме
я i- scheduleActions с использованием gocron (при необходимости передавать ресурсы)
ii i- - это специальная подпрограмма, выполняющая задачу по мере необходимости с использованием заданного ресурса (например, DB)
У меня мало случаев, когда нужно перезапустить службу mysql.
Затем, как и ожидалось, я получаю сообщение об ошибке с неверным подключением. что-то вроде
[mysql] packets.go:33: unexpected EOF
[mysql] packets.go:130: write tcp 127.0.0.1:36191->127.0.0.1:3306: write: broken pipe
[mysql] connection.go:312: invalid connection
Чтобы обойти это, я сделал реализацию, чтобы получить соединение с БД в подпрограмме и закрыть с помощью defer db.close(). С этим я получаю ошибку, связанную со слишком большим количеством открытых подключений. Я проверил правильное закрытие строк, а также использование сканирования. И см. Рекомендации.
Я хотел бы понять, как сделать доступ к открытию и закрытию базы данных в моем случае.
Вы можете использовать sync.Once
чтобы предотвратить это:
var conn *sql.DB // Set package-wide, but not exported
var once sync.Once
func GetConnection() *sql.DB {
once.Do(func() {
var err error
if conn, err = sql.Open("postgres", "<credentials>"); err != nil {
log.Panic(err)
}
conn.SetMaxOpenConns(20) // Sane default
conn.SetMaxIdleConns(0)
conn.SetConnMaxLifetime(time.Nanosecond)
})
return conn
}
Прочтите это: https://aaronoellis.com/articles/preventing-max-connection-errors-in-go