2009-11-24 2 views
4

Это может звучать как вопрос о нобе, но это первый раз, когда я ступаю по территории базы данных.
От here я получил информацию, чтоИспользование JNDI для соединений с базой данных

Наиболее эффективный способ реализации связи между сервером и базой данных заключается в создании пула соединений базы данных . Создание нового соединения для каждого запроса клиента может быть очень трудоемким, особенно для приложений, которые непрерывно получают большое количество запросов.

и в учебнике используется источник данных JNDI.

Мое приложение также похоже (но я не буду использовать Tomcat, только сокеты), и мой сервер будет получать запросы от нескольких клиентов, но я не понимаю, почему я должен использовать источник данных JNDI, почему не удается сервер поддерживает одно открытое соединение с базой данных, и по мере поступления запроса клиента он обрабатывает запрос и передает данные клиенту.

В худшем случае, если мне нужен JNDI, как я могу реализовать его с помощью моего серверного приложения?

ответ

4

Таким образом, это клиентское приложение? Приложение и база данных обычно разговаривают друг с другом, используя соединение, полученное с помощью DriverManager#getConnection()? Если это так, то вам не обязательно нужен JNDI, чтобы заставить пул соединений работать. Единственное, о чем идет речь, будет уже достаточно. Например, C3P0 или Apache Commons DBCP (я бы рекомендовал C3P0, DBCP - односторонний). Просто замените его DriverManager#getConnection().

Edit: ответить на ваши комментарии:

Сервер будет говорить с базой данных и клиенты подключаются к серверу, так что я не знаю, можно ли назвать это клиентское приложение.

Я на самом деле имею в виду простой Java-приложение, которое не запускается внутри контейнера Java EE. Паскаль сформулировал это лучше.

На самом деле, я немного смущен тем, как работает объединение пулов, выполняется ли каждое соединение в его собственном потоке? есть ли какой-либо документ/книга, чтобы помочь мне лучше понять эти концепции по сравнению с не объединенным соединением?

Чтобы начать, пул соединений открывает соединение и удерживает его открытым до тех пор, пока не будет установлен установленный тайм-аут. Пул подключений обертывает/decorates соединение с его собственной реализацией. Пул соединений может одновременно открывать и удерживать сконфигурированное количество подключений. Когда вы позвоните по номеру getConnection(), он немедленно предоставит вам уже открытое соединение. Когда вы вызываете close() на соединение, он вернет соединение обратно в пул для будущих запросов. Это означает, что вам все равно придется писать код JDBC обычным способом: приобрести и закрыть Connection, Statement и ResultSet в кратчайший возможный объем. Закройте все их в блоке finally.Если ваш код JDBC уже хорошо написан, на самом деле толькоDriverManager#getConnection() необходимо заменить. Поскольку вы должны открывать и закрывать Connection в том же блоке методов, он обычно запускается в том же потоке. Пул соединений будет беспокоиться о том, что Connection не приобретается другими потоками, пока ваш код не назовет close() на Connection.

Вы можете найти here хорошую статью, чтобы получить представление о том, как работает объединение пулов под капотом (позаботьтесь: не используйте его для производства и не делайте это самостоятельно, просто получите всю идею) , Для реальной работы используйте существующую тщательно разработанную и надежную структуру объединения пулов.

+0

Сервер будет разговаривать с базой данных, а клиенты подключаются к серверу, поэтому я не буду знать, следует ли называть это клиентское приложение. И да, серверная часть кода использует DriverManager.getConnection(), спасибо за ссылку C3P0. –

+0

Спасибо за ясное, краткое объяснение, я сделал несколько примеров кода с помощью DriverManager, но я поддерживал соединение открытым. Мои клиенты используют сокеты для подключения к серверу и будут оставаться подключенными. Каждый клиент работает в своем потоке чтения/записи, поэтому, если сервер хочет передать данные, он просто запрашивает данные из базы данных (из уже открытого соединения) и передает их клиенту. Правильно ли это, или я должен закрыть соединение как можно скорее? –

+2

Обычная практика заключается в том, что вы должны закрыть соединение в блоке finally, чтобы избежать утечек ресурсов и/или потенциальных сбоев приложений в случае, если у вас открыто несколько соединений и/или что DB отключает соединение. Чтобы улучшить производительность соединения, лучше всего использовать пул соединений. Просто убедитесь, что вы не настроили тайм-аут пула соединений (т. Е. Как долго держать соединение открытым) дольше, чем собственный тайм-аут соединения БД. – BalusC

2

Мое приложение также похоже (но я не буду использовать Tomcat, только сокеты), и мой сервер будет получать запросы от нескольких клиентов, но я не понимаю, почему я должен использовать источник данных JNDI, почему сервер не поддерживает одно открытое соединение с базой данных и при поступлении запроса клиента обрабатывает запрос и передает данные клиенту.

Ну, вы могли бы. Но что, если у вас несколько клиентов, и если вам приходится выполнять одновременные запросы? Конечно, вы можете поддерживать одно соединение открытым для каждого клиента, но это не очень хорошо масштабируется (что может быть не проблемой в вашем контексте). Тем не менее, традиционным способом решения этой проблемы является использование пула соединений (и получение дополнительных услуг, например, проверка соединения, продление подключения) и использование его для получения соединения «по требованию».

Если вы не используете контекст контейнера J2EE, используйте автономную пул соединений пула, например c3p0 (предпочитайте c3p0 по DBCP, который считается устаревшим и менее надежным при загрузке) и забудьте JNDI (это просто стандартный способ получить ручку в пуле соединений при запуске внутри контейнера J2EE).

Для получения более подробной информации и образцов кода см. C3p0's documentation, это довольно ясно.

+0

Я не знал, что JNDI использовался только в контексте контейнера J2EE, спасибо за то, что он это заметил, а также для ссылок c3p0 и DBCP. –

+0

На самом деле я немного смущен тем, как работает объединение пулов, работает ли каждое соединение в своем потоке? есть ли какой-либо документ/книга, чтобы помочь мне лучше понять эти концепции по сравнению с не объединенным соединением? –

2

JNDI для соединений с базой данных решает ситуацию, когда разработчики приложений не те, кто управляет подключениями к базе данных.

Таким образом, разработчик приложения может указать, сколько одновременных соединений требуется их приложениям. Затем администратор сервера определит пул соединений с базой данных. Приложение просматривает пул.

Ни приложение, ни разработчик приложения не должны знать учетные данные, необходимые для подключения к базе данных. Кроме того, администратор сервера может определить пул соединений в разных размерах в зависимости от среды развертывания, и приложение изолировано от знания о таких различиях.

Поскольку ваше приложение является сервером, приложение, следовательно, несет ответственность за определение и управление соединением (ами) в базе данных.

+0

Как разработчик приложения оценивает количество одновременных подключений. Если приложение и разработчик приложений не знают параметры безопасности (учетные данные), где они указаны? Загружаются ли они в файл конфигурации? –

+1

Для подсчета подключений, один из вариантов заключается в том, чтобы просто догадаться, а затем выполнить проверку нагрузки на ожидаемом максимальном объеме производства и контролировать использование соединения. Используйте около 110% от максимального значения, которое вы наблюдали в тесте нагрузки. Или вы можете проверить использование приложений своими приложениями и попытаться найти обоснованное предположение, основанное на доступе к БД, количестве одновременных клиентов и т. Д. Учетные данные хранятся в конфигурации сервера приложений. Серверы делают это по-другому, но они предоставляют стандартный пул соединений JNDI. – shadit

1

Выдача другой ссылки на другой пул соединений: BoneCP (http://jolbox.com). Тесты показывают, что он быстрее, чем C3P0/DBCP.

P.S. Не видел, чтобы DBCP блокировался либо в моих многопоточных тестах.