Postgres+JDBC+Connection pool+LS2J

R

rinsk

Lotus team
12.11.2009
1 049
86
В одном Web прикладе активно используются LS агенты, которые через LS2J обращаются к базе postgres через JDBC.
Заметны задержки времени при установлении соединения с базой.
Задумался о Database Connection Pool (dbcp) - но вот никак не понятно, как это можно реализовать.
На сколько я понял, в Домино надо поднять сервлет и\или как то через OSGI dbcp и как то через LS2J обращаться к этому dbcp...
Наставьте на путь истинный, коллеги.
Переписывание на java + xpages не предлагать - там наворочено куча бизнес логики...
 
R

romych2004

а каждый раз долгий коннект или только первый?
вообще, нашел что при первом коннекте он тянет метаданные и это занимает долгое время.. надо наверно в драйвере смотреть, какие есть параметры



С пулом не работал, ниче подсказать не могу
 
garrick

garrick

Lotus team
26.10.2009
1 024
81
Идея с пулом заключается в том, что сервер при старте устанавливает соединение в реляционной базой и держит его всё время. Как реализовать это в Domino - проблема. Как установить соединение при старте, как держать его всё время открытым и как обратиться к нему из агента или другого кода? Тут надо какой-то плагин к серверу писать. Настроить какое-нибудь соединение через Data Connections не пробовали? Хотя, мне кажется, эту штуку индусы не трогали ещё с 4-ой или 5-ой версии (когда оно там появилось), вряд ли можно к ней подключить какую-то современную базу. Насколько я помню там была самая "новая" версия Oracle 8-я.
 
garrick

garrick

Lotus team
26.10.2009
1 024
81
написать свой класс и положить его в jvm/lib/ext
К стати, можно попробовать. Ведь всё что лежит в ext загружается в память при старте сервера. Не силён в устройстве JVM. а как сделать так, чтобы при загрузке выполнился код подключения к СУБД? Как-то надо же это инициализировать.
 
R

rinsk

Lotus team
12.11.2009
1 049
86
а каждый раз долгий коннект или только первый?
вообще, нашел что при первом коннекте он тянет метаданные и это занимает долгое время.. надо наверно в драйвере смотреть, какие есть параметры



С пулом не работал, ниче подсказать не могу
Первый коннект - потом следующие запросы быстро
[doublepost=1501158040,1501157826][/doublepost]
К стати, можно попробовать. Ведь всё что лежит в ext загружается в память при старте сервера. Не силён в устройстве JVM. а как сделать так, чтобы при загрузке выполнился код подключения к СУБД? Как-то надо же это инициализировать.
Ну это да - именно надо инциализировать некий стандартный dbcp - их много разных. Имхо например апачевый не достаточно положить в ext - нужно создать контекст исполнения... Но думаю это ничего не даст, потому что по идее коннект драйвера идет к некомому синглтону ему известному. Будет ли контекст доступен агенту - э вопрос...
 
K

Kee_Keekkenen

Well-known member
05.09.2006
634
4
К стати, можно попробовать. Ведь всё что лежит в ext загружается в память при старте сервера. Не силён в устройстве JVM. а как сделать так, чтобы при загрузке выполнился код подключения к СУБД? Как-то надо же это инициализировать.
пишешь библиотеку, в которой будет реализация синглетона на базе PGPoolingDataSource, который будет создавать подключения и управлять их жизнью.. при первом обращении это добро будет создаваться, а далее переиспользоваться созданные соединения с базой
 
R

rinsk

Lotus team
12.11.2009
1 049
86
Его не рекомендуют использовать , оставили ради совместимости:

Я тут вот наткунлся на
Relational Database Management (RDBMS) Support using XPages

в общем то для xPages там все есть)
интересно - можно ли через LS2J до туда достучатся?:)
 
erdi

erdi

Well-known member
20.08.2008
264
17
Как это сделать в среде OSGI я знаю, когда есть 1 бандл, который раздает коннекты, и другие бандлы, которые берут свободный коннект из пула. А вот как это воспроизвести с агентами, я что-то призадумался. При запуске бандлов, они работают в одном контексте OSGI, поэтому и есть такая возможность. А вот при запуске агента, происходит запуск в своем контексте и как достучаться до другого контекста, я пока не знаю.
Для среды OSGI метод в следующем.
В OSGI среде есть понятие services, которые как и классы можно экспортировать и импортировать(описывается в манифесте). Поэтому в бандле, который раздает коннекты, создается DataSource и помещается в контейнер, например я пользуюсь hikaricp. Созданный DataSource экспортируется как сервис с определенным именем. Во 2-м бандле мы импортируем сервис по имени, т.е. фактически 2-й бандл будет импортировать DataSource из первого. Соответственно при обращении к DataSource во 2-м бандле, он через сервис, получает его из 1-го. После завершения операции, коннект возвращается в пул hikaricp. В случаи, если коннект битый(любая ошибка при соединении), hikaricp обновляет коннект в своем пуле.
Но это работает в OSGI. Как это переделать на агенты, а тут еще LS.....надо думать
[doublepost=1501566946,1501566523][/doublepost]Хм....как вариант заюзать это все через REST/SOAP сервисы, ну или на крайний случай веб сервлет. Будет 2 бандла. 1-й DataSource с hikaricp, 2-й веб сервис. LS локально, если запуск происходит на сервере или удаленно, вызывает этот сервис, который в свою очередь выполняет определенные действия с базой, получая коннекты из 1-го бандла. Результат возвращается в LS агента или java агента. Оба они умеют работать с веб сервисами
[doublepost=1501567216][/doublepost]как создать бандл REST Applications, можно посмотреть в блоге( ). Мне более комфортно их создавать с apache cxf, но и так можно.
 
lmike

lmike

нет, пердело совершенство
Lotus team
27.08.2008
7 258
439
экспортируется как сервис с определенным именем.
в это отношении мало чем отличается от сорса на хэпагах, когда по урлу получаем выборку из БД, единственный момент - сохранение авторизации изнутри, я эту тему не педалил
 
erdi

erdi

Well-known member
20.08.2008
264
17
в это отношении мало чем отличается от сорса на хэпагах, когда по урлу получаем выборку из БД, единственный момент - сохранение авторизации изнутри, я эту тему не педалил
проблема не в том, что необходимо запустить для коннекта к базе, а проблема в том, что запускать надо то, что уже находится в активном статусе. За счет этого и достигается быстродействие, т.к. не тратится время на создание нового коннекта. А сходить по урлу или вызвать агента это теже фаберже, только в профиль. На этом в скорости не выиграть, особенно в многопоточности. Если xpages может вызывать контекст osgi бандлов, то хорошо(я в последнее время не слежу за лотусом). А если тупо как агента, то плохо.
 
R

rinsk

Lotus team
12.11.2009
1 049
86
проблема не в том, что необходимо запустить для коннекта к базе, а проблема в том, что запускать надо то, что уже находится в активном статусе. За счет этого и достигается быстродействие, т.к. не тратится время на создание нового коннекта. А сходить по урлу или вызвать агента это теже фаберже, только в профиль. На этом в скорости не выиграть, особенно в многопоточности.
....
Совершенно верно - реч идет об использовании Connection Pool из LS2J.
Наметились 2 направления:
1 - написать либу. которая делает синглтон объект из hikaricp\DBCP или еще подобного и по идее этот объект должен бытьт виден для всех вызовов через LS2J.
2 - в библиотеке использовать com.ibm.xsp.extlibx.* и дергать через ls2j...

ну и третий вариант - забить на все и делать на ява))
 
erdi

erdi

Well-known member
20.08.2008
264
17
Совершенно верно - реч идет об использовании Connection Pool из LS2J.
Наметились 2 направления:
1 - написать либу. которая делает синглтон объект из hikaricp\DBCP или еще подобного и по идее этот объект должен бытьт виден для всех вызовов через LS2J.
2 - в библиотеке использовать com.ibm.xsp.extlibx.* и дергать через ls2j...

ну и третий вариант - забить на все и делать на ява))
из всего этого, я не понял как Вы собрались решать проблему получения объекта коннекта к базе, при условии что агенты запускаются по событию. Т.е. в момент запуска агента, Вы должны каким-то образом из какого-то контекста, который был ранее запущен, вытащить данный объект. Положив jar в lib на сервере, Вы получите новый экземпляр класса, который умеет создавать коннекты, но не запушенный экземпляр класса, который может отдать уже созданные соединения. Другой разговор, если в агенте используется код для многопоточной работы с БД, и в этом случаи, во время работы агента, получим ускорение для одновременной работы с БД. Но когда агент завершится - объект с коннектами к БД также умрет. И следующий вызов агента не возьмет предыдущий, а создаст себе свой. Получите тоже самое, что и сейчас.
Концепция osgi решает эту проблему, т.к. все запущенные бандлы находятся в одном контексте и при запуске бандла можно создавать объекты, которые потом можно в этом контексте отдавать другим бандлам.
Xpages хоть и пользуется osgi, но что-то я не припомню как можно манипулировать объектами в osgi среде, через xpages
 
lmike

lmike

нет, пердело совершенство
Lotus team
27.08.2008
7 258
439
Положив jar в lib на сервере, Вы получите новый экземпляр класса, который умеет создавать коннекты, но не запушенный экземпляр класса, который может отдать уже созданные соединения.
время жизни "таких" объектов (из либ в jvm/lb/ext) равно времени жизни jvm, а не агента
 
erdi

erdi

Well-known member
20.08.2008
264
17
время жизни "таких" объектов (из либ в jvm/lb/ext) равно времени жизни jvm, а не агента
пример можно как взять объект, созданный в другой jar, которая лежит в lib на сервере из агента
[doublepost=1501672807,1501666752][/doublepost]посмотрел исходники примера для Relational Database Management (RDBMS) Support using XPages, на предмет того, как они берут пулл коннектов. Они это делают через эту конструкцию
Код:
public Connection getConnection() throws SQLException {
        if(connection==null) {
            connection = JdbcUtil.getConnection(FacesContext.getCurrentInstance(),connectionName);
        }
        return connection;
    }
в JdbcUtil, из пакета com.ibm.xsp.extlib.relational.util, все сводится к этой конструкции
Код:
 public static Connection createNamedConnection(FacesContext context, String name) throws SQLException {
        try {
            String jndiName = name;
            if (!jndiName.startsWith("java:")) { // $NON-NLS-1$
                jndiName = JndiRegistry.getJNDIBindName(name);
            }
            final InitialContext ctx = new InitialContext();
            final DataSource ds = (DataSource) ctx.lookup(jndiName);
            if (ds != null) {
                return ds.getConnection();
            }
            return null;
        } catch (final NamingException ex) {
            throw (SQLException) new SQLException().initCause(ex);
        }
    }
Т.е коннекты регистрируются как сервис Jndi в FacesContext. А это означает, что пулл коннектов будет активен только для текущей Xpages. И будет обслуживать все запросы к БД через пулл, только для этого приложения. Открыв другую Xpages(здесь имеется ввиду Xpages из другой базы) -> создастся новый пулл
 
lmike

lmike

нет, пердело совершенство
Lotus team
27.08.2008
7 258
439
пример можно как взять объект, созданный в другой jar, которая лежит в lib на сервере из агента

создаем класс и кладем куда "положено"
в агенте получаем объект
для случая с ленивой инициализацией получим несколько объектов (если класслоадеры будут разные)
[doublepost=1501693783,1501676974][/doublepost]менее древний подход
[doublepost=1502098197][/doublepost]
ну и третий вариант - забить на все и делать на ява))
вполне резонно, еще и DOTS подключить, тогда не будет оверхеда на запуск, о кот. говорил @erdi
 
  • Нравится
Реакции: Vertigo
Мы в соцсетях:  ТелеграмВконтактеДзенФейсбукТвиттерЮтуб