Improve ActiveMQ connection pool configuration

Closes gh-1598
This commit is contained in:
n27 2016-03-09 16:47:30 +01:00 committed by Stephane Nicoll
parent fa84b179a8
commit e41d42171b
8 changed files with 161 additions and 29 deletions

View File

@ -34,6 +34,7 @@ import org.springframework.context.annotation.Configuration;
* @author Stephane Nicoll
* @author Phillip Webb
* @author Andy Wilkinson
* @author Aurélien Leboulanger
* @since 1.1.0
*/
@Configuration
@ -41,7 +42,7 @@ import org.springframework.context.annotation.Configuration;
class ActiveMQConnectionFactoryConfiguration {
@Bean
@ConditionalOnProperty(prefix = "spring.activemq", name = "pooled", havingValue = "false", matchIfMissing = true)
@ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "false", matchIfMissing = true)
public ActiveMQConnectionFactory jmsConnectionFactory(ActiveMQProperties properties) {
return new ActiveMQConnectionFactoryFactory(properties)
.createConnectionFactory(ActiveMQConnectionFactory.class);
@ -51,14 +52,28 @@ class ActiveMQConnectionFactoryConfiguration {
static class PooledConnectionFactoryConfiguration {
@Bean(destroyMethod = "stop")
@ConditionalOnProperty(prefix = "spring.activemq", name = "pooled", havingValue = "true", matchIfMissing = false)
public PooledConnectionFactory pooledJmsConnectionFactory(
ActiveMQProperties properties) {
return new PooledConnectionFactory(
@ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "true", matchIfMissing = false)
public PooledConnectionFactory pooledJmsConnectionFactory(ActiveMQProperties properties) {
PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory(
new ActiveMQConnectionFactoryFactory(properties)
.createConnectionFactory(ActiveMQConnectionFactory.class));
ActiveMQProperties.Pool pool = properties.getPool();
pooledConnectionFactory.setMaxConnections(pool.getMaxConnections());
pooledConnectionFactory.setIdleTimeout(pool.getIdleTimeMillis());
pooledConnectionFactory.setMaximumActiveSessionPerConnection(pool.getMaxSessionsPerConnection());
pooledConnectionFactory.setExpiryTimeout(pool.getExpiryTimeMillis());
pooledConnectionFactory.setTimeBetweenExpirationCheckMillis(pool.getTimeBetweenEvictionRunsMillis());
return pooledConnectionFactory;
}
@Bean
@ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "false", matchIfMissing = true)
public ActiveMQConnectionFactory jmsConnectionFactory(ActiveMQProperties properties) {
return new ActiveMQConnectionFactoryFactory(properties).createConnectionFactory(ActiveMQConnectionFactory.class);
}
}
}

View File

@ -23,6 +23,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
*
* @author Greg Turnquist
* @author Stephane Nicoll
* @author Aurélien Leboulanger
*/
@ConfigurationProperties(prefix = "spring.activemq")
public class ActiveMQProperties {
@ -38,12 +39,6 @@ public class ActiveMQProperties {
*/
private boolean inMemory = true;
/**
* Specify if a PooledConnectionFactory should be created instead of a regular
* ConnectionFactory.
*/
private boolean pooled;
/**
* Login user of the broker.
*/
@ -54,6 +49,8 @@ public class ActiveMQProperties {
*/
private String password;
private Pool pool = new Pool();
public String getBrokerUrl() {
return this.brokerUrl;
}
@ -70,14 +67,6 @@ public class ActiveMQProperties {
this.inMemory = inMemory;
}
public boolean isPooled() {
return this.pooled;
}
public void setPooled(boolean pooled) {
this.pooled = pooled;
}
public String getUser() {
return this.user;
}
@ -94,4 +83,93 @@ public class ActiveMQProperties {
this.password = password;
}
public Pool getPool() {
return this.pool;
}
public void setPool(Pool pool) {
this.pool = pool;
}
protected static class Pool {
/**
* Specify if a PooledConnectionFactory should be created instead of a regular
* ConnectionFactory.
*/
private boolean enabled;
/**
* Sets the maximum number of pooled Connections.
*/
private int maxConnections = 1;
/**
* Sets the idle timeout value for Connection's that are created by this pool in Milliseconds.
*/
private int idleTimeMillis = 30 * 1000;
/**
* Allow connections to expire, irrespective of load or idle time.
*/
private long expiryTimeMillis = 0L;
/**
* Sets the maximum number of active sessions per connection.
*/
private int maxSessionsPerConnection = 500;
/**
* Sets the number of milliseconds to sleep between runs of the idle Connection eviction thread.
*/
private long timeBetweenEvictionRunsMillis = -1L;
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public int getMaxConnections() {
return this.maxConnections;
}
public void setMaxConnections(int maxConnections) {
this.maxConnections = maxConnections;
}
public int getIdleTimeMillis() {
return this.idleTimeMillis;
}
public void setIdleTimeMillis(int idleTimeMillis) {
this.idleTimeMillis = idleTimeMillis;
}
public long getExpiryTimeMillis() {
return this.expiryTimeMillis;
}
public void setExpiryTimeMillis(long expiryTimeMillis) {
this.expiryTimeMillis = expiryTimeMillis;
}
public int getMaxSessionsPerConnection() {
return this.maxSessionsPerConnection;
}
public void setMaxSessionsPerConnection(int maxSessionsPerConnection) {
this.maxSessionsPerConnection = maxSessionsPerConnection;
}
public long getTimeBetweenEvictionRunsMillis() {
return this.timeBetweenEvictionRunsMillis;
}
public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
}
}

View File

@ -36,6 +36,7 @@ import org.springframework.context.annotation.Primary;
* Configuration for ActiveMQ XA {@link ConnectionFactory}.
*
* @author Phillip Webb
* @author Aurélien Leboulanger
* @since 1.2.0
*/
@Configuration
@ -54,7 +55,7 @@ class ActiveMQXAConnectionFactoryConfiguration {
}
@Bean
@ConditionalOnProperty(prefix = "spring.activemq", name = "pooled", havingValue = "false", matchIfMissing = true)
@ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "false", matchIfMissing = true)
public ActiveMQConnectionFactory nonXaJmsConnectionFactory(
ActiveMQProperties properties) {
return new ActiveMQConnectionFactoryFactory(properties)
@ -62,17 +63,25 @@ class ActiveMQXAConnectionFactoryConfiguration {
}
@ConditionalOnClass(PooledConnectionFactory.class)
@ConditionalOnProperty(prefix = "spring.activemq", name = "pooled", havingValue = "true", matchIfMissing = false)
@ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "true", matchIfMissing = false)
static class PooledConnectionFactoryConfiguration {
@Bean(destroyMethod = "stop")
public PooledConnectionFactory pooledNonXaJmsConnectionFactory(
ActiveMQProperties properties) {
return new PooledConnectionFactory(
PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory(
new ActiveMQConnectionFactoryFactory(properties)
.createConnectionFactory(ActiveMQConnectionFactory.class));
}
ActiveMQProperties.Pool pool = properties.getPool();
pooledConnectionFactory.setExpiryTimeout(pool.getExpiryTimeMillis());
pooledConnectionFactory.setMaxConnections(pool.getMaxConnections());
pooledConnectionFactory.setIdleTimeout(pool.getIdleTimeMillis());
pooledConnectionFactory.setMaximumActiveSessionPerConnection(pool.getMaxSessionsPerConnection());
pooledConnectionFactory.setTimeBetweenExpirationCheckMillis(pool.getTimeBetweenEvictionRunsMillis());
return pooledConnectionFactory;
}
}
}

View File

@ -54,6 +54,7 @@ import static org.mockito.Mockito.mock;
*
* @author Greg Turnquist
* @author Stephane Nicoll
* @author Aurélien Leboulanger
*/
public class JmsAutoConfigurationTests {
@ -309,7 +310,7 @@ public class JmsAutoConfigurationTests {
@Test
public void testActiveMQOverriddenPool() {
load(TestConfiguration.class, "spring.activemq.pooled:true");
load(TestConfiguration.class, "spring.activemq.pool.enabled:true");
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
PooledConnectionFactory pool = this.context
.getBean(PooledConnectionFactory.class);
@ -323,7 +324,7 @@ public class JmsAutoConfigurationTests {
@Test
public void testActiveMQOverriddenPoolAndStandalone() {
load(TestConfiguration.class, "spring.activemq.pooled:true",
load(TestConfiguration.class, "spring.activemq.pool.enabled:true",
"spring.activemq.inMemory:false");
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
PooledConnectionFactory pool = this.context
@ -338,7 +339,7 @@ public class JmsAutoConfigurationTests {
@Test
public void testActiveMQOverriddenPoolAndRemoteServer() {
load(TestConfiguration.class, "spring.activemq.pooled:true",
load(TestConfiguration.class, "spring.activemq.pool.enabled:true",
"spring.activemq.brokerUrl:tcp://remote-host:10000");
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
PooledConnectionFactory pool = this.context

View File

@ -21,6 +21,7 @@ import javax.jms.JMSException;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.pool.PooledConnectionFactory;
import org.junit.Test;
import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration;
@ -37,6 +38,7 @@ import static org.mockito.Mockito.mockingDetails;
* Tests for {@link ActiveMQAutoConfiguration}
*
* @author Andy Wilkinson
* @author Aurélien Leboulanger
*/
public class ActiveMQAutoConfigurationTests {
@ -59,9 +61,30 @@ public class ActiveMQAutoConfigurationTests {
.isTrue();
}
@Test
public void custompooledConnectionFactoryConfiguration() {
load(EmptyConfiguration.class,
"spring.activemq.pool.enabled:true",
"spring.activemq.pool.max-connections:256",
"spring.activemq.pool.idle-time-millis:512",
"spring.activemq.pool.max-sessions-per-connection:1024",
"spring.activemq.pool.time-between-eviction-runs-millis:2048",
"spring.activemq.pool.expiry-time-millis:4096"
);
ConnectionFactory connectionFactory = this.context.getBean(ConnectionFactory.class);
assertThat(connectionFactory).isInstanceOf(PooledConnectionFactory.class);
PooledConnectionFactory pooledConnectionFactory = (PooledConnectionFactory) connectionFactory;
assertThat(pooledConnectionFactory.getMaxConnections()).isEqualTo(256);
assertThat(pooledConnectionFactory.getIdleTimeout()).isEqualTo(512);
assertThat(pooledConnectionFactory.getMaximumActiveSessionPerConnection()).isEqualTo(1024);
assertThat(pooledConnectionFactory.getTimeBetweenExpirationCheckMillis()).isEqualTo(2048);
assertThat(pooledConnectionFactory.getExpiryTimeout()).isEqualTo(4096);
}
@Test
public void pooledConnectionFactoryConfiguration() throws JMSException {
load(EmptyConfiguration.class, "spring.activemq.pooled:true");
load(EmptyConfiguration.class, "spring.activemq.pool.enabled:true");
ConnectionFactory connectionFactory = this.context
.getBean(ConnectionFactory.class);
assertThat(connectionFactory).isInstanceOf(PooledConnectionFactory.class);

View File

@ -24,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link ActiveMQProperties} and ActiveMQConnectionFactoryFactory.
*
* @author Stephane Nicoll
* @author Aurélien Leboulanger
*/
public class ActiveMQPropertiesTests {

View File

@ -726,8 +726,13 @@ content into your application; rather pick only the properties that you need.
spring.activemq.broker-url= # URL of the ActiveMQ broker. Auto-generated by default. For instance `tcp://localhost:61616`
spring.activemq.in-memory=true # Specify if the default broker URL should be in memory. Ignored if an explicit broker has been specified.
spring.activemq.password= # Login password of the broker.
spring.activemq.pooled=false # Specify if a PooledConnectionFactory should be created instead of a regular ConnectionFactory.
spring.activemq.user= # Login user of the broker.
spring.activemq.pool.enabled=false # Specify if a PooledConnectionFactory should be created instead of a regular ConnectionFactory.
spring.activemq.pool.max-connections=1 # The maximum number of pooled Connections
spring.activemq.pool.max-sessions-per-connection=500 # The maximum number of active sessions per connection
spring.activemq.pool.time-between-eviction-runs-millis=-1 # The number of milliseconds to sleep between runs of the idle Connection eviction thread.
spring.activemq.pool.idle-time-millis=30000 # The idle timeout value for Connection's that are created by this pool (in Milliseconds)
spring.activemq.pool.expiry-time-millis=0 # Allow connections to expire, irrespective of load or idle time
# ARTEMIS ({sc-spring-boot-autoconfigure}/jms/artemis/ArtemisProperties.{sc-ext}[ArtemisProperties])
spring.artemis.embedded.cluster-password= # Cluster password. Randomly generated on startup by default.

View File

@ -1,2 +1,2 @@
spring.activemq.in-memory=true
spring.activemq.pooled=false
spring.activemq.pool.enabled=false