connection pool

Пул соединений (Connection pool)

Продолжаем писать сайт на java и сегодня мы поговорим о такой теме как пул соединение или connection pool на английском. Напомню, что это уже четвертая статья, посвященная простому java веб приложению. Остальные можно найти в рубрике Java web.

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

Во избежании таких проблем есть пул соединений, который открывает соединение только первый раз, а при закрытии соединения он не закрывает его, а отправляет в пул в случае если кто-то будет делать очередной запрос. По сути, приложение работает через специальный драйвер, который является оберткой для обычного jdbc драйвера и который имеет дополнительный функционал по работе с пулом.

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

Для особенно активных, можно написать свой connection pool: класс, который буде иметь список соединений. У него будет переопределена функция close, которая будет возвращать соединение обратно в список и много других плюшек вроде таймера открытого соединения. Когда нет конекшина долгое время, соединение закрывается.

Мы не будем изобретать свой велосипед, а воспользуемся готовыми решениями. Так как мы используем Tomcat возьмем его реализацию пула соединений.

Для этого нужно в папке webapp создать папку META-INF и в ней создать xml файл context.xml.

создание context.xml

Далее нужно вставить настройки нашего пула в этот файл:

Код    
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <Context>
  3.     <!-- Specify a JDBC datasource -->
  4.     <Resource name="jdbc/имяПула" - можно выбрать произвольно
  5.              auth="Container"
  6.              type="javax.sql.DataSource"
  7.              username="Пользователь"
  8.              password="Пароль"
  9.              driverClassName="com.mysql.jdbc.Driver" - если используете mysql
  10.              url="jdbc:mysql://хост:3306/имяБазы?autoReconnect=true"
  11.              validationQuery="select 1"
  12.              maxActive="10"
  13.              maxIdle="4"/>
  14.  
  15. </Context>

 

Здесь указано по минимуму настроек. Полагаю, комментарии излишни.

Теперь осталось только использовать этот код в нашем приложении.

Создадим класс ConnectonPool и сделаем его singletone. Для тех, кто не знает: это когда нельзя создать больше одного экземпляра данного класса.

Для этого делается приватный конструктор и для доступа к экземпляру класса создается специальный метод, который возвращает только один экземпляр класса.

Код    
  1. private ConnectionPool(){
  2.         //private constructor
  3.     }
  4.  
  5.     private static ConnectionPool instance = null;
  6.    
  7.     public static ConnectionPool getInstance(){
  8.         if (instance==null)
  9.             instance = new ConnectionPool();
  10.         return instance;
  11.     }

 

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

Код    
  1. public Connection getConnection(){
  2.         Context ctx;
  3.         Connection c = null;
  4.         try {
  5.             ctx = new InitialContext();
  6.             DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/имяПула");
  7.              c = ds.getConnection();
  8.         } catch (NamingException e) {
  9.             e.printStackTrace();
  10.         } catch (SQLException e) {
  11.             e.printStackTrace();
  12.         }
  13.         return c;
  14.     }

 

Тут нужно немного комментариев.

Context — это интерфейс, который представляет собой контекст именования, который состоит из набора привязок имени к объекту. InitialContext — класс, который является исходным контекстом для выполнения операций именования. А говоря простым языком, Context, InitialContext позволяют нам иметь доступ к службам имен и каталогов. Для любопытных советую почитать о Java Naming and Directory Interface (JNDI). Метод lookup() извлекает объект по ссылке. В нашем случае он вынимает объект и кастит его к DataSource. Таким образом мы получили DataSource, который вернет нам Connection.

Полный код:

Код    
  1. import java.sql.Connection;
  2. import java.sql.SQLException;
  3.  
  4. import javax.naming.Context;
  5. import javax.naming.InitialContext;
  6. import javax.naming.NamingException;
  7. import javax.sql.DataSource;
  8.  
  9. public class ConnectionPool {
  10.    
  11.     private ConnectionPool(){
  12.         //private constructor
  13.     }
  14.  
  15.     private static ConnectionPool instance = null;
  16.    
  17.     public static ConnectionPool getInstance(){
  18.         if (instance==null)
  19.             instance = new ConnectionPool();
  20.         return instance;
  21.     }
  22.    
  23.     public Connection getConnection(){
  24.         Context ctx;
  25.         Connection c = null;
  26.         try {
  27.             ctx = new InitialContext();
  28.             DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/mydatabase");
  29.              c = ds.getConnection();
  30.         } catch (NamingException e) {
  31.             e.printStackTrace();
  32.         } catch (SQLException e) {
  33.             e.printStackTrace();
  34.         }
  35.         return c;
  36.     }
  37. }

Это все о пуле соединений. Как всегда, видео, где я все это приконнектил к проекту и ссылка на гитхаб: https://github.com/caligula95/simplewebapp-part4

Добавить комментарий