![]() |
|
|||
WebMoney: WMZ Z294115950220 WMR R409981405661 WME E134003968233 |
Visa 4274 3200 2453 6495 |
Объединение связи это метод создания и управления пулом связей, которые
готовы к употреблению любым
потоком, которому они нужны.
Объединение связи может значительно увеличить производительность
приложения, уменьшая полное использование ресурсов. Для большинства запросов нужен только поток, чтобы иметь доступ к связи
JDBC, когда они активно обрабатывают
транзакции, которая часто занимает только миллисекунды.
Если не обрабатывает транзакцию, связь простаивает. Объединение связи
позволяет неработающей связи использоваться некоторым другим потоком, чтобы
сделать полезную работу. На практике, когда поток должен сделать работу с JDBC, это просит связь из
пула. Когда поток закончит использование связи, он возвращает ее в пул, чтобы
она могла использоваться любыми другими потоками. Когда связь дана из пула, она используется исключительно потоком, который
запросил ее. С программной точки зрения это аналогично тому, что поток
каждый раз вызвал Главные преимущества для объединения связи: Уменьшенное время создания связи. Хотя это обычно не проблема с быстрой установкой связи, которую MySQL
предлагает по сравнению с другими базами данных, создание новых связей JDBC
все еще требует издержек в драйвере JDBC и сетевом слое, которых можно
избежать, если связи будут переработаны. Упрощенная модель программирования. Используя объединение связи, каждый отдельный поток может действовать, как
будто это создало свою собственную связь JDBC, позволив вам использовать
прямые методы программирования JDBC. Использование ресурсов грамотно. Если вы создаете новую связь каждый раз, когда она нужна потоку вместо
того, чтобы использовать объединение связи, использование ресурсов вашего
запроса может быть расточительным, а это может привести к непредсказуемым
поведениям для вашего запроса, когда он находится под большой нагрузкой.
Понятие объединения связи в JDBC было стандартизировано через
дополнительные интерфейсы JDBC 2.0, и у всех серверов основного приложения
есть реализация их API, которая работает с MySQL Connector/J. Обычно вы формируете пул связи в своих конфигурационных файлах сервера
приложений и получаете доступ к нему через Java Naming and Directory
Interface (JNDI). Следующий код показывает, как вы могли бы использовать пул
связи от приложения, развернутого в сервере приложений J2EE: Пример 8.1. Connector/J: Использование пула связи
с сервером приложений J2EE Как показано в примере выше, после получения JNDI
Используя объединение связи, всегда удостоверяйтесь, что закрываются связи
и что-либо созданное ими (запросы или наборы результатов). Это правило
применяет, неважно, что происходит в вашем коде (исключения, поток контроля и
т.д.). Когда эти объекты закрываются, они могут быть снова использованы,
иначе они будут переплетены, что означает, что ресурсы сервера MySQL, которые
они представляют (такие как буфера, блокировки или сокеты) заняты в течение
некоторого времени или в худшем случае могут быть заняты навсегда. У каждой связи с MySQL есть накладные расходы (память, CPU, контекстные
переключения и т.д.) на обоих сторонах клиент-сервера. Каждая связь
ограничивает, сколько ресурсов там доступно вашему запросу, а также серверу
MySQL. Многие из этих ресурсов будут использоваться безотносительно того,
делает ли связь на самом деле какую-либо полезную работу! Пулы связи могут
быть настроены, чтобы максимизировать работу, держа использование ресурса
ниже пункта, где ваш запрос начнет терпеть неудачу, а не
просто работать медленнее. Оптимальный размер для пула связи зависит от ожидаемой нагрузки
и среднего времени транзакции базы данных. На практике оптимальный размер
пула связи может быть меньшим, чем вы могли бы ожидать. Если вы берете
приложение Oracle's Java Petstore, например, пул связи в 15-20 связей может
служить относительно умеренной нагрузке (600 параллельных пользователей) с
использованием MySQL и Tomcat с приемлемым временем отклика. Чтобы правильно измерить пул связи для вашего запроса,
создайте скрипты нагрузочного теста такими инструментами, как Apache JMeter
или The Grinder и проведите нагрузочный тест вашего приложения. Легкий способ определить отправную точку состоит в том, чтобы формировать
неограниченный максимальный размер пула связи,
выполнить нагрузочный тест и измерить самый большой объем одновременно
используемых связей. Можно тогда работать, чтобы определить
минимальное и максимальное количества объединенных связей, которые дают
лучшей эффект для конкретного приложения. MySQL Connector/J может проверить связь, выполнив пинг сервера.
В случае уравновешенных по нагрузке связей это выполняется для всех активных
объединенных внутренних связей, которые сохраняются. Это выгодно для
приложений Java, используя пулы связи, поскольку пул может использовать эту
функцию, чтобы утвердить связи. В зависимости от вашего пула связи и
конфигурации, эта проверка может быть выполнена в разное время: Прежде чем пул возвращает связь приложению. Когда приложение возвращает связь в пул. Во время периодических проверок неработающих связей. Чтобы использовать эту функцию, определите запрос проверки в своем пуле
связи, который начинается с Очень важно, что синтаксис определяется правильно.
Синтаксис должен быть точным по причинам эффективности, поскольку этот тест
сделан для каждого запроса, который выполняется: Ни один из следующих отрывков не будет работать, потому что синтаксис
пинга чувствителен к пробелам, регистру и размещению: Все предыдущие запросы выпустят нормальный
Если ваше развертывание Connector/J использует пул связи, который
позволяет вам определять запрос проверки, надо использовать в своих интересах
его, но гарантировать, что запрос начинается
точно с
Глава 8. Объединение связи в Connector/J
Как объединение связи работает
DriverManager.getConnection()
,
когда была нужна связь JDBC. С объединением связи ваш поток может
использовать новую или уже существующую связь.Выгода объединения связи
Используя объединение связи с Connector/J
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class MyServletJspOrEjb {
public void doSomething() throws Exception {
/*
* Create a JNDI Initial context to be able to
* lookup the Data Source
*
* In production-level code, this should be cached as
* an instance or static variable, as it can
* be quite expensive to create a JNDI context.
*
* Note: This code only works when you are using servlets
* or EJBs in a J2EE application server. If you are
* using connection pooling in standalone Java code, you
* will have to create/configure datasources using whatever
* mechanisms your particular connection pooling library provides.
*/
InitialContext ctx = new InitialContext();
/*
* Lookup the DataSource, which will be backed by a pool
* that the application server provides. DataSource instances
* are also a good candidate for caching as an instance
* variable, as JNDI lookups can be expensive as well.
*/
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/MySQLDB");
/*
* The following code is what would actually be in your
* Servlet, JSP or EJB 'service' method...where you need
* to work with a JDBC connection.
*/
Connection conn = null;
Statement stmt = null;
try {
conn = ds.getConnection();
/*
* Now, use normal JDBC programming to work with
* MySQL, making sure to close each resource when you're
* finished with it, which permits the connection pool
* resources to be recovered as quickly as possible
*/
stmt = conn.createStatement();
stmt.execute("SOME SQL QUERY");
stmt.close();
stmt = null;
conn.close();
conn = null;
} finally {
/*
* close any jdbc instances here that weren't
* explicitly closed during normal code path, so
* that we don't 'leak' resources...
*/
if (stmt != null) {
try {
stmt.close();
} catch (sqlexception sqlex) {
// ignore, as we can't do anything about it here
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (sqlexception sqlex) {
// ignore, as we can't do anything about it here
}
conn = null;
}
}
}
}
InitialContext
и поиска
DataSource
остальная часть кода следует
знакомым соглашениям JDBC.Калибровка пула связи
Утверждение связей
/* ping */
.
Обратите внимание на то, что синтаксис должен быть точно как определен.
Это предписывает драйверу послать пинг в сервер и возвращает фиктивный легкий
набор результатов. Используя ReplicationConnection
или LoadBalancedConnection
, пинг
пошлют через все активные связи.
protected static final String PING_MARKER = "/* ping */";
...
if (sql.charAt(0) == '/') {
if (sql.startsWith(PING_MARKER)) {
doPingInstead();
...
}
}
sql = "/* PING */ SELECT 1";
sql = "SELECT 1 /* ping*/";
sql = "/*ping*/ SELECT 1";
sql = " /* ping */ SELECT 1";
sql = "/*to ping or not to ping*/ SELECT 1";
SELECT
, но
НЕ будут преобразованы в пинг.
Далее для уравновешенных по нагрузке связей, запрос будет выполнен для одной
связи во внутреннем пуле, вместо того, чтобы проверить каждую основную
физическую связь. Это приводит к неактивным физическим связям, принимающим
несвежее состояние. Если Connector/J позже повторно балансирует, он мог бы
выбрать неактивную связь, приводящую к исключению, передаваемому к
приложению. Чтобы помочь предотвратить это, можно использовать
loadBalanceValidateConnectionOnSwapServer
,
чтобы проверить связь перед использованием./* ping */
.
Это особенно важно, если вы используете выравнивание нагрузки или
репликацию с Connector/J, поскольку это поможет поддержать связи, которые
иначе отвалятся, вызвав проблемы позже.
Найди своих коллег! |
Вы можете
направить письмо администратору этой странички, Алексею Паутову.