Низкая производительность потока spring.io из ActiveMQ в OracleAQ с XA

У меня есть поток интеграции Spring, который соединяет ActiveMQ с OracleAQ. См. пример проекта на GitHub — https://github.com/cknzl2014/springio-ora-xa/tree/atomikos.

Когда я запускаю его без XA, он молниеносно быстр. С XA он обрабатывает только 1–2 сообщения в секунду. При профилировании приложения я вижу, что для каждого сообщения устанавливается новое физическое соединение, и при этом выдается запрос метаданных на oracle db. Но я не понимаю, почему он это делает, и как я могу предотвратить это.

Есть ли у кого-нибудь из вас опыт работы с OracleAQ и XA? Может ли это быть проблемой с менеджером транзакций XA (я использую Atomikos)?

Спасибо за помощь, Крис


person Christoph K    schedule 19.11.2017    source источник


Ответы (2)


Мы нашли решение проблемы. Он состоит из четырех шагов.

Шаг 1. Используйте новейшие клиентские библиотеки Oracle
Первый шаг – использование новейших клиентских библиотек Oracle 12c. В ojdbc8.jar были внесены значительные улучшения, например. теперь они используют хранимые процедуры для получения метаданных.
Это увеличило пропускную способность примерно до 10 msgs/s.

Шаг 2. Правильная настройка пула соединений
Вторым шагом было улучшение пула соединений в соответствии со статьей http://thinkfunctional.blogspot.ch/2012/05/atomikos-and-oracle-aq-pooling-problem.html:

<bean id="oraXaDataSource" primary="true"
    class="oracle.jdbc.xa.client.OracleXADataSource" destroy-method="close">
    <property name="URL" value="${oracle.url}" />
    <property name="user" value="${oracle.username}" />
    <property name="password" value="${oracle.password}" />
</bean>

<bean id="atomikosOraclaDataSource"
    class="org.springframework.boot.jta.atomikos.AtomikosDataSourceBean">
    <property name="uniqueResourceName" value="xaOracleAQ" />
    <property name="xaDataSource" ref="oraXaDataSource" />
    <property name="poolSize" value="5" />
</bean>

<bean id="OracleAQConnectionFactory" class="oracle.jms.AQjmsFactory" factory-method="getConnectionFactory">
    <constructor-arg ref="atomikosOraclaDataSource" />
</bean>

Одна только эта конфигурация приводит к исключениям из-за «автоматической фиксации» соединения с Oracle.

Шаг 3. Установите для autoCommit значение false
Третьим шагом было задание следующего системного свойства Java (см. https://docs.oracle.com/database/121/JAJDB/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_AUTOCOMMIT):

-DautoCommit=false

Но затем пропускная способность снова упала до 1-2 msg/s.

Шаг 4. Установите для oracle.jdbc.autoCommitSpecCompliant значение false
Последним шагом была установка следующего системного свойства Java (см. https://docs.oracle.com/database/121/JAJDB/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_AUTO_COMMIT_SPEC_COMPLIANT):

-Doracle.jdbc.autoCommitSpecCompliant=false

Теперь мы получаем пропускную способность 80 msgs/s.

Заключение
Установка для oracle.jdbc.autoCommitSpecCompliant значения false не является элегантной, но решает проблему. Мы должны продолжить расследование, чтобы увидеть, как мы можем обойти эту проблему, не устанавливая oracle.jdbc.autoCommitSpecCompliant в false.

Большое спасибо Дани Штайнманн (stonie) за помощь!

P.S.: Я обновил пример проекта на GitHub — https://github.com/cknzl2014/springio-ora-xa/tree/atomikos.

person Christoph K    schedule 24.11.2017

Прежде всего, вы должны быть уверены, что используете пул для соединений JDBC.

С другой стороны, вы можете использовать ChainedTransactionManager вместо XA для двух целевых менеджеров транзакций - JMS и JDBC.

Также см. некоторую информацию в Расширения JDBC.

Также есть некоторые Oracle AQ API также в этом проекте.

person Artem Bilan    schedule 20.11.2017
comment
Я прочитал статья о JMS и JDBC. Очень интересно. Особенно мне нравится шаблон Best Efforts 1 PC, который будет намного быстрее, но требует идемпотентных приемников. - person Christoph K; 24.11.2017