Сравнение производительности пулов соединений JDBC
У кого-нибудь есть какая-либо информация, сравнивающая характеристики производительности различных реализаций ConnectionPool?
Фон: у меня есть приложение, которое запускает обновления базы данных в фоновых потоках до экземпляра mysql в том же окне. Использование источника данных com.mchange.v2.c3p0.ComboPooledDataSource даст нам случайные SocketExceptions: com.mysql.jdbc.CommunicationsException: сбой канала связи из-за основного исключения:
** BEGIN NESTED EXCEPTION **
java.net.SocketException
MESSAGE: Broken pipe
STACKTRACE:
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
Увеличение таймаута подключения mysql увеличило частоту этих ошибок.
Эти ошибки исчезли при переключении на другой пул соединений (com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource); однако производительность может быть хуже, а профиль памяти заметно ниже (мы получаем меньше и намного больше GC, чем пул c3p0).
5 ответов
Какой бы пул соединений вы не использовали, вы должны предположить, что соединение может быть случайно закрыто в любой момент, и заставить ваше приложение справиться с ним.
В случае с постоянным соединением с БД в "доверенной" сети часто случается так, что ОС применяет ограничение по времени к тому, как долго соединения могут быть открыты, или периодически запускает некоторый код "очистки соединения". Но причина не имеет большого значения - это всего лишь часть сетевой жизни, в которой вы должны предполагать, что соединение может быть "вырвано из-под ваших ног", и иметь дело с этим сценарием соответственно.
Учитывая это, я действительно не вижу смысла в структуре пула соединений, которая не позволяет вам обрабатывать этот случай программно.
(Между прочим, это еще один из моих случаев, когда я рад, что просто пишу свой собственный код пула соединений; никаких "черных ящиков" таинственным образом не съедает память и не нужно рыться в поисках "магического параметра"...)
Возможно, вы захотите взглянуть на некоторые контрольные цифры на http://jolbox.com/ - сайте, на котором размещен BoneCP, пул соединений, который работает быстрее, чем C3P0 и DBCP.
Вы пробовали Apache DBCP? Я не знаю о c3po, но DBCP может обрабатывать простаивающие соединения по-разному:
- Это может удалить неактивные соединения из пула
- Может выполнить запрос на незанятые соединения после определенного периода бездействия.
Он также может проверить, является ли соединение действительным непосредственно перед передачей его приложению, выполнив запрос к нему; если он получает исключение, он сбрасывает это соединение и пытается установить соединение с другим (или создает новое, если может). Намного надежнее.
У меня также всплыла эта ошибка с mysql & c3p0 - я пробовал разные вещи и в итоге заставил ее исчезнуть. Я не могу вспомнить, но то, что могло бы решить это, был флаг autoReconnect а-ля
url="jdbc:mysql://localhost:3306/database?autoReconnect=true"
Сломанная труба
Это примерно означает, что другая сторона прервала / тайм-аут / закрыла соединение. Разве вы не держите связи так долго открытыми? Убедитесь, что ваш код правильно закрывает все ресурсы JDBC (Connection
, Statement
а также ResultSet
) в блоке наконец.
Увеличение таймаута подключения mysql увеличило частоту этих ошибок.
Позаботьтесь о том, чтобы этот тайм-аут не превышал настройки тайм-аута DB