Этот вопрос задавали пару раз в SO и много раз на других сайтах. Но ответа я не получил.
Моя проблема:
У меня есть веб-приложение java, которое использует простой JDBC для подключения к базе данных mysql через сервер приложений Glassfish.
Я использовал пул соединений на сервере Glassfish со следующими конфигурациями:
Начальный размер пула: 25
Максимальный размер бассейна: 100
Pool Resize Количество: 2
Idle Timeout: 300 секунд
Максимальное время ожидания: 60 000 миллисекунд
Приложение было развернуто в течение последних 3 месяцев, и оно работает безупречно.
Но с последних 2 дней на момент входа в систему появляется следующая ошибка.
Частичный StackTrace
com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: No operations allowed after connection closed.Connection was implicitly closed due to underlying exception/error:
** BEGIN NESTED EXCEPTION **
com.mysql.jdbc.CommunicationsException
MESSAGE: Communications link failure due to underlying exception:
** BEGIN NESTED EXCEPTION **
java.io.EOFException
MESSAGE: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
STACKTRACE:
java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1997)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2411)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2916)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3256)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1313)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1448)
............
............
my application traces....
Что вызвало эту ошибку внезапно? Я потерял много времени для этого.
EDIT: Проблема сохраняется даже после перезапуска сервера. В соответствии с DBA две важные конфигурации сервера mysql:
wait_timeout: 1800 секунд
connect_timeout: 10 секунд
ПРИМЕЧАНИЕ. Другие приложения, развернутые на одном сервере, подключающиеся к одной базе данных и использующие разные пулы, работают плавно.
EDIT-2: После прочтения многих вещей и ожиданий какого-то положительного результата я внес эти изменения в пул соединений.
Макс. время ожидания: 0 (раньше это было 60 секунд)
Проверка подключения: Требуется |
Метод проверки: таблица
Имя таблицы: Демо-версия
Подтвердить как минимум: 40 секунд
попытки повторной попытки создания: 1
Интервалы повторения: 5 секунд
Максимальное использование подключения: 5
И это работало, так как приложение работает в течение 3 дней. Но у меня получился очень странный и интересный результат. Наблюдая за пулом соединений, я нашел эти цифры:
NumConnAcquired: 44919 Count
NumConnReleased: 44919 Count
NumConnCreated: 9748 Count
NumConnDestroyed: 9793 Count
NumConnFailedValidation: 70 Count
NumConnFree: 161 граф
NumConnUsed: -136 Count
Как может NumConnFree
стать 161, поскольку у меня есть Maximum Pool Size = 100
?
Как может NumConnUsed
стать -136, отрицательное число ?
Как может NumConnDestroyed
NumConnCreated
?