Використання connection pool в tomcat

У наш час важко уявити собі веб-додаток, яка не використала б базу даних для своїх потреб. При роботі з базою даних дуже важливо стежити за сполуками до бази і вчасно звільняти їх. Для цих цілей розробники веб-додатків пишуть так звані Connection Pools (або ж використовують / виправляють існуючі).

Одним з кращих сервлет-контейнерів є Apache Tomcat. Tomcat добре ще й тим, що він використовує свій власний DBCP (Database Connection Pool).

Для того, щоб налаштувати Tomcat на цю базу, необхідно в конфігураційному фалі conf \ server.xml в розділ Context (якщо немає, необхідно створити його всередині розділу Host безпосередньо перед його закінченням) додати наступні рядки:

За допомогою цієї конфігурації створюється Data Source з ім'ям newDB. Розглянемо параметри цього об'єкта.

Параметр factory говорить про те, яку фабрику потрібно використовувати для створення об'єктів, що реалізують інтерфейс DataSource. Наступний параметр являє собою URL для доступу до бази даних. Параметри username і password містять соответсвенно ім'я користувача / схеми і пароль. Ім'я драйвера бази даних вказано в параметрі driverClassName.

Наступні параметри відповідають безпосередньо за Connection Pool. Розглянемо їх трохи докладніше.

maxActive - максимальна кількість з'єднань, які будуть міститися в пулі. Якщо значення цього параметра встановити в 0, то обмеження на кількість підключень до бази не буде. У конфігурації самого сервера баз данн такий параметр теж існує. Думаю не варто пояснювати, чому його значення повинно бути більше, ніж maxActive.

maxIdle - максимальна кількість простоюють з'єднань, які залишатимуться в пулі. При значенні цього параметра рівним нулю, обмежень не буде.

maxWait - якщо час очікування з'єднання перевищить значення параметра maxWait (в мілісекундах), користувач отримає Exception. При значенні maxWait рівним -1, час очікування не обмежена.

Прошу звертаючись вашу увагу на наступну дуже важливу річ. Tomcat працює під віртуальною машиною (JVM). Щоб звільнити пам'ять JVM використовує збирач сміття (garbage collector). GC має дуже високий пріоритет і при звільненні пам'яті Tomcat буде входити в стан очікування (на частки секунди, рідше - на кілька секунд). При маленьких значеннях maxWait, з'єднання може не встановитися через таймаута. Значення 10000 в переважній більшості випадків буде оптимальним.

removeAbandoned - при установці цього парамеров в true, занедбані з'єднання будуть звільнені, коли кількість вільних з'єднань в пулі невелика.

removeAbandonedTimeout - цей параметр вказує в секундах час, через яке будь простоює з'єднання буде вважатися занедбаним.

Після цього, потрібно налаштувати наше веб-додаток для роботи з DataSource. Робиться це так, у файлі-дескрипторі web.xml пишемо:

Нарешті ми і дісталися до використання всього вишенапісанного на практиці. Щоб доступитися до нашого DataSource через JNDI і створювати з'єднання з базою можна написати такий собі клас (імпорт пакетів і обробка помилок опущені):

Занедбані з'єднання - це умовний термін. Tomcat позначає з'єднання як занедбане за значенням параметра removeAbandonedTimeout. Це зроблено з тих міркувань, що в деяких ситуаціях idle з'єднання можуть виникнуть в результаті некоректної роботи програми (збоїв). Тому потрібно мати хоч якусь можливість відстежити це і звільнити такого роду connections.

Тег дозволяє задати режим аутентифікації користувача при спробі установки з'єднання з БД.

Значення «Container» говорить, що аутентифікацію буде виконувати контейнер на основі наданих йому ідентифікатора і пароля (або сертифіката) користувача (наприклад, реквізити користувача вказувалися в дескрипторі для пулу з'єднань з обраної СУБД). Інше можливе значення - «Application» - говорить про те, що параметри користувача повинні явно вказуватися на рівні Java-коду при зверненні до фабрики з'єднань з СУБД.

У мене є деякі побоювання:

1. Tomcat тільки створює ресурси за допомогою фабрик, в даному випадку пул сполук перехідних. Але по-моєму він не керує їх жизень циклом, тобто його не цікавить їх коректне знищення. Необхідно в server.xml прописати слухача життєвого циклу сервера, який закриє пул.

2. Пул прописаний в server.xml, а не в контест додатки, якщо передбачається розшарити його на кілька додатків, то слід остерігатися:

2.1 Витоки сполук перехідних в одному додатку, виведуть з ладу, інші додатки використовують цей пул.

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