Repository: activemq-artemis Updated Branches: refs/heads/1.x ec085b8ea -> 8a3f4ccd6
ARTEMIS-1124 JDBC Network Timeout configuration (cherry picked from commit a639774b54d31fd06c906f8ae42b9733f96e569b) Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/87bde15f Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/87bde15f Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/87bde15f Branch: refs/heads/1.x Commit: 87bde15f383f97371fd3932b34f540a250ae3d30 Parents: ec085b8 Author: Francesco Nigro <[email protected]> Authored: Thu Apr 20 12:43:40 2017 +0200 Committer: Francesco Nigro <[email protected]> Committed: Thu Apr 20 19:45:19 2017 +0200 ---------------------------------------------------------------------- .../config/ActiveMQDefaultConfiguration.java | 8 ++++++ .../jdbc/store/drivers/AbstractJDBCDriver.java | 29 ++++++++++++++++++++ .../store/file/JDBCSequentialFileFactory.java | 8 ++++++ .../storage/DatabaseStorageConfiguration.java | 10 +++++++ .../deployers/impl/FileConfigurationParser.java | 1 + .../paging/impl/PagingStoreFactoryDatabase.java | 12 ++++++-- .../impl/journal/JDBCJournalStorageManager.java | 19 +++++++++++-- .../resources/schema/artemis-configuration.xsd | 7 +++++ docs/user-manual/en/persistence.md | 8 ++++-- 9 files changed, 96 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/87bde15f/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java ---------------------------------------------------------------------- diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java index 0f26a00..5d86243 100644 --- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java +++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java @@ -16,6 +16,8 @@ */ package org.apache.activemq.artemis.api.config; +import java.util.concurrent.TimeUnit; + import org.apache.activemq.artemis.ArtemisConstants; import org.apache.activemq.artemis.api.core.SimpleString; @@ -429,6 +431,8 @@ public final class ActiveMQDefaultConfiguration { // Default large messages table name, used with Database storage type private static final String DEFAULT_PAGE_STORE_TABLE_NAME = "PAGE_STORE"; + private static final int DEFAULT_JDBC_NETWORK_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(20); + // Default period to wait between connection TTL checks public static final long DEFAULT_CONNECTION_TTL_CHECK_INTERVAL = 2000; @@ -1172,6 +1176,10 @@ public final class ActiveMQDefaultConfiguration { return DEFAULT_PAGE_STORE_TABLE_NAME; } + public static int getDefaultJdbcNetworkTimeout() { + return DEFAULT_JDBC_NETWORK_TIMEOUT; + } + public static long getDefaultConnectionTtlCheckInterval() { return DEFAULT_CONNECTION_TTL_CHECK_INTERVAL; } http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/87bde15f/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/AbstractJDBCDriver.java ---------------------------------------------------------------------- diff --git a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/AbstractJDBCDriver.java b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/AbstractJDBCDriver.java index 1828911..fcbf90d 100644 --- a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/AbstractJDBCDriver.java +++ b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/AbstractJDBCDriver.java @@ -26,6 +26,7 @@ import java.sql.SQLWarning; import java.sql.Statement; import java.util.Arrays; import java.util.Properties; +import java.util.concurrent.Executor; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -51,18 +52,28 @@ public abstract class AbstractJDBCDriver { private DataSource dataSource; + private Executor networkTimeoutExecutor; + + private int networkTimeoutMillis; + public AbstractJDBCDriver() { + this.networkTimeoutExecutor = null; + this.networkTimeoutMillis = -1; } public AbstractJDBCDriver(SQLProvider sqlProvider, String jdbcConnectionUrl, String jdbcDriverClass) { this.jdbcConnectionUrl = jdbcConnectionUrl; this.jdbcDriverClass = jdbcDriverClass; this.sqlProvider = sqlProvider; + this.networkTimeoutExecutor = null; + this.networkTimeoutMillis = -1; } public AbstractJDBCDriver(DataSource dataSource, SQLProvider provider) { this.dataSource = dataSource; this.sqlProvider = provider; + this.networkTimeoutExecutor = null; + this.networkTimeoutMillis = -1; } public void start() throws SQLException { @@ -76,6 +87,8 @@ public abstract class AbstractJDBCDriver { public AbstractJDBCDriver(Connection connection, SQLProvider sqlProvider) { this.connection = connection; this.sqlProvider = sqlProvider; + this.networkTimeoutExecutor = null; + this.networkTimeoutMillis = -1; } public void stop() throws SQLException { @@ -127,6 +140,17 @@ public abstract class AbstractJDBCDriver { throw e; } } + if (this.networkTimeoutMillis >= 0 && this.networkTimeoutExecutor != null) { + try { + connection.setNetworkTimeout(this.networkTimeoutExecutor, this.networkTimeoutMillis); + } catch (SQLException e) { + logger.warn(JDBCUtils.appendSQLExceptionDetails(new StringBuilder(), e)); + ActiveMQJournalLogger.LOGGER.warn("Unable to set a network timeout on the JDBC connection"); + } catch (Throwable throwable) { + //it included SecurityExceptions and UnsupportedOperationException + logger.warn("Unable to set a network timeout on the JDBC connection", throwable); + } + } } } @@ -240,4 +264,9 @@ public abstract class AbstractJDBCDriver { this.dataSource = dataSource; } + public void setNetworkTimeout(Executor executor, int milliseconds) { + this.networkTimeoutExecutor = executor; + this.networkTimeoutMillis = milliseconds; + } + } http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/87bde15f/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/file/JDBCSequentialFileFactory.java ---------------------------------------------------------------------- diff --git a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/file/JDBCSequentialFileFactory.java b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/file/JDBCSequentialFileFactory.java index d5a92a2..ae2e793 100644 --- a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/file/JDBCSequentialFileFactory.java +++ b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/file/JDBCSequentialFileFactory.java @@ -101,6 +101,14 @@ public class JDBCSequentialFileFactory implements SequentialFileFactory, ActiveM return dbDriver; } + /** + * @see Connection#setNetworkTimeout(Executor, int) + **/ + public JDBCSequentialFileFactory setNetworkTimeout(Executor executor, int milliseconds) { + this.dbDriver.setNetworkTimeout(executor, milliseconds); + return this; + } + @Override public SequentialFileFactory setDatasync(boolean enabled) { return this; http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/87bde15f/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/storage/DatabaseStorageConfiguration.java ---------------------------------------------------------------------- diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/storage/DatabaseStorageConfiguration.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/storage/DatabaseStorageConfiguration.java index eb8b435..76626c0 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/storage/DatabaseStorageConfiguration.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/storage/DatabaseStorageConfiguration.java @@ -40,6 +40,8 @@ public class DatabaseStorageConfiguration implements StoreConfiguration { private SQLProvider.Factory sqlProviderFactory; + private int jdbcNetworkTimeout = ActiveMQDefaultConfiguration.getDefaultJdbcNetworkTimeout(); + @Override public StoreType getStoreType() { return StoreType.DATABASE; @@ -125,4 +127,12 @@ public class DatabaseStorageConfiguration implements StoreConfiguration { public void setSqlProvider(SQLProvider.Factory sqlProviderFactory) { this.sqlProviderFactory = sqlProviderFactory; } + + public int getJdbcNetworkTimeout() { + return this.jdbcNetworkTimeout; + } + + public void setJdbcNetworkTimeout(int jdbcNetworkTimeout) { + this.jdbcNetworkTimeout = jdbcNetworkTimeout; + } } http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/87bde15f/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java ---------------------------------------------------------------------- diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java index 087a6fb..c36699e 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java @@ -1159,6 +1159,7 @@ public final class FileConfigurationParser extends XMLConfigurationUtil { conf.setPageStoreTableName(getString(storeNode, "page-store-table-name", conf.getPageStoreTableName(), Validators.NO_CHECK)); conf.setJdbcConnectionUrl(getString(storeNode, "jdbc-connection-url", conf.getJdbcConnectionUrl(), Validators.NO_CHECK)); conf.setJdbcDriverClassName(getString(storeNode, "jdbc-driver-class-name", conf.getJdbcDriverClassName(), Validators.NO_CHECK)); + conf.setJdbcNetworkTimeout(getInteger(storeNode, "jdbc-network-timeout", conf.getJdbcNetworkTimeout(), Validators.NO_CHECK)); return conf; } http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/87bde15f/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryDatabase.java ---------------------------------------------------------------------- diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryDatabase.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryDatabase.java index afe9708..a8c6127 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryDatabase.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryDatabase.java @@ -117,6 +117,10 @@ public class PagingStoreFactoryDatabase implements PagingStoreFactory { String driverClassName = dbConf.getJdbcDriverClassName(); pagingFactoryFileFactory = new JDBCSequentialFileFactory(dbConf.getJdbcConnectionUrl(), driverClassName, JDBCUtils.getSQLProvider(driverClassName, pageStoreTableNamePrefix, SQLProvider.DatabaseStoreType.PAGE), executorFactory.getExecutor(), criticalErrorListener); } + final int jdbcNetworkTimeout = dbConf.getJdbcNetworkTimeout(); + if (jdbcNetworkTimeout >= 0) { + pagingFactoryFileFactory.setNetworkTimeout(this.executorFactory.getExecutor(), jdbcNetworkTimeout); + } pagingFactoryFileFactory.start(); started = true; } @@ -224,8 +228,12 @@ public class PagingStoreFactoryDatabase implements PagingStoreFactory { } else { sqlProvider = JDBCUtils.getSQLProvider(dbConf.getJdbcDriverClassName(), getTableNameForGUID(directoryName), SQLProvider.DatabaseStoreType.PAGE); } - - return new JDBCSequentialFileFactory(pagingFactoryFileFactory.getDbDriver().getConnection(), sqlProvider, executorFactory.getExecutor(), criticalErrorListener); + final JDBCSequentialFileFactory fileFactory = new JDBCSequentialFileFactory(pagingFactoryFileFactory.getDbDriver().getConnection(), sqlProvider, executorFactory.getExecutor(), criticalErrorListener); + final int jdbcNetworkTimeout = dbConf.getJdbcNetworkTimeout(); + if (jdbcNetworkTimeout >= 0) { + fileFactory.setNetworkTimeout(this.executorFactory.getExecutor(), jdbcNetworkTimeout); + } + return fileFactory; } private String getTableNameForGUID(String guid) { http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/87bde15f/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JDBCJournalStorageManager.java ---------------------------------------------------------------------- diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JDBCJournalStorageManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JDBCJournalStorageManager.java index 5592c9e..4b8392d 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JDBCJournalStorageManager.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JDBCJournalStorageManager.java @@ -55,8 +55,10 @@ public class JDBCJournalStorageManager extends JournalStorageManager { @Override protected synchronized void init(Configuration config, IOCriticalErrorListener criticalErrorListener) { try { - DatabaseStorageConfiguration dbConf = (DatabaseStorageConfiguration) config.getStoreConfiguration(); - + final DatabaseStorageConfiguration dbConf = (DatabaseStorageConfiguration) config.getStoreConfiguration(); + final JDBCJournalImpl bindingsJournal; + final JDBCJournalImpl messageJournal; + final JDBCSequentialFileFactory largeMessagesFactory; if (dbConf.getDataSource() != null) { SQLProvider.Factory sqlProviderFactory = dbConf.getSqlProviderFactory(); if (sqlProviderFactory == null) { @@ -71,6 +73,19 @@ public class JDBCJournalStorageManager extends JournalStorageManager { messageJournal = new JDBCJournalImpl(dbConf.getJdbcConnectionUrl(), driverClassName, JDBCUtils.getSQLProvider(driverClassName, dbConf.getMessageTableName(), SQLProvider.DatabaseStoreType.MESSAGE_JOURNAL), scheduledExecutorService, executorFactory.getExecutor(), criticalErrorListener); largeMessagesFactory = new JDBCSequentialFileFactory(dbConf.getJdbcConnectionUrl(), driverClassName, JDBCUtils.getSQLProvider(driverClassName, dbConf.getLargeMessageTableName(), SQLProvider.DatabaseStoreType.LARGE_MESSAGE), executor, criticalErrorListener); } + final int networkTimeout = dbConf.getJdbcNetworkTimeout(); + if (networkTimeout >= 0) { + bindingsJournal.setNetworkTimeout(executorFactory.getExecutor(), networkTimeout); + } + if (networkTimeout >= 0) { + messageJournal.setNetworkTimeout(executorFactory.getExecutor(), networkTimeout); + } + if (networkTimeout >= 0) { + largeMessagesFactory.setNetworkTimeout(executorFactory.getExecutor(), networkTimeout); + } + this.bindingsJournal = bindingsJournal; + this.messageJournal = messageJournal; + this.largeMessagesFactory = largeMessagesFactory; largeMessagesFactory.start(); } catch (Exception e) { criticalErrorListener.onIOException(e, e.getMessage(), null); http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/87bde15f/artemis-server/src/main/resources/schema/artemis-configuration.xsd ---------------------------------------------------------------------- diff --git a/artemis-server/src/main/resources/schema/artemis-configuration.xsd b/artemis-server/src/main/resources/schema/artemis-configuration.xsd index af0148e..6fa5fc4 100644 --- a/artemis-server/src/main/resources/schema/artemis-configuration.xsd +++ b/artemis-server/src/main/resources/schema/artemis-configuration.xsd @@ -1707,6 +1707,13 @@ </xsd:documentation> </xsd:annotation> </xsd:element> + <xsd:element name="jdbc-network-timeout" type="xsd:int" minOccurs="0" maxOccurs="1"> + <xsd:annotation> + <xsd:documentation> + The JDBC network connection timeout in milliseconds. + </xsd:documentation> + </xsd:annotation> + </xsd:element> </xsd:all> </xsd:complexType> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/87bde15f/docs/user-manual/en/persistence.md ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/persistence.md b/docs/user-manual/en/persistence.md index 50d9dc9..7e07773 100644 --- a/docs/user-manual/en/persistence.md +++ b/docs/user-manual/en/persistence.md @@ -298,9 +298,9 @@ The message journal is configured using the following attributes in data files on the journal The default for this parameter is `30` - + - `journal-datasync` (default: true) - + This will disable the use of fdatasync on journal writes. ### An important note on disabling disk write cache. @@ -424,6 +424,10 @@ To configure Apache ActiveMQ Artemis to use a database for persisting messages a The fully qualified class name of the desired database Driver. +- `jdbc-network-timeout` + + The JDBC network connection timeout in milliseconds. The default value + is 20000 milliseconds (ie 20 seconds). ## Configuring Apache ActiveMQ Artemis for Zero Persistence
