加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

springboot-34-activemq配置连接池

(2017-09-26 20:34:45)
分类: 微服务

一般我们在springboot中配置activemq只有以下一行:

spring.activemq.broker-url=tcp://localhost:61616

但如果mq服务器压力过大,可能会导致out of memory,此时就需要进行优化,首先考虑使用mq连接池,避免broker频繁创建连接,减小服务器开销。

1.      引入activemq-poolpom

首先需要引入activemq-pool

<dependency>
   <groupId>
org.springframework.boot</groupId>
   <artifactId>
spring-boot-starter-activemq</artifactId>
</dependency>

<dependency>
   <groupId>
org.apache.activemq</groupId>
   <artifactId>
activemq-pool</artifactId>
</dependency>

 

2.      application配置

我们可以在application.yml中加入:

 

spring:
  activemq:
    broker-url: 
tcp://localhost:61616
    
pool:
      enabled: 
true
      
configuration:
        max-connections: 
2

spring.activemq.pool.enabled=true表示打开连接池

spring.activemq.pool.maxConnections=2表示最大连接数为2

但如果我们使用了自定义的mq配置中注入了ActiveMQConnectionFactory,例如:

@Configuration
public class ActivemqComponent {

    
@Autowired
    
private ActiveMQConnectionFactorconnectionFactory;

    

    
@Bean(name "queueListenerFactory")
    
public DefaultJmsListenerContainerFactory queueListenerFactory(){
        DefaultJmsListenerContainerFactory factory = 
new DefaultJmsListenerContainerFactory();
        
factory.setConnectionFactory(connectionFactory);
        
factory.setPubSubDomain(false);
//        factory.setMessageConverter(new SimpleMessageConverter());
        
return factory;
    
}

直接启动项目就会出现以下错误:

Field connectionFactory in com.scn7th.mqConfig.ActivemqComponent required a bean of type 'org.apache.activemq.ActiveMQConnectionFactory' that could not be found.

- Bean method 'jmsConnectionFactory' in 'ActiveMQConnectionFactoryConfiguration' not loaded because @ConditionalOnProperty (spring.activemq.pool.enabled=false) found different value in property 'enabled'

- Bean method 'nonXaJmsConnectionFactory' not loaded because @ConditionalOnBean (types: org.springframework.boot.jta.XAConnectionFactoryWrapper; SearchStrategy: all) did not find any beans

其中第二句是关键,也就是说,springboot-activemq-starter中的自定义配置ActiveMQConnectionFactoryConfiguration中注入了ActiveMQConnectionFactoryActiveMQConnectionFactoryspring.activemq.pool.enabled=false时才会创建,所以我们此时再注入ActiveMQConnectionFactory肯定在spring中找不到。我们可以看到,在ActiveMQConnectionFactoryConfiguration类中定义了PooledConnectionFactory,而它的创建条件正是spring.activemq.pool.enabled=true,所以我们必须使用PooledConnectionFactory来代替ActiveMQConnectionFactory注入到ActiveMqConfig中,需要注意的是,我们注入的PooledConnectionFactory在包org.apache.activemq.pool下,而不是org.apache.activemq.pool.jms下的PooledConnectionFactory,如果引用了错误的类则会报错。

【注】springbootActiveMQConnectionFactoryConfiguration.java



package org.springframework.boot.autoconfigure.jms.activemq;

import 
javax.jms.ConnectionFactory;

import 
org.apache.activemq.ActiveMQConnectionFactory;
import 
org.apache.activemq.pool.PooledConnectionFactory;

import 
org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import 
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import 
org.springframework.boot.context.properties.ConfigurationProperties;
import 
org.springframework.context.annotation.Bean;
import 
org.springframework.context.annotation.Configuration;


@Configuration
@ConditionalOnMissingBean
(ConnectionFactory.class)
class ActiveMQConnectionFactoryConfiguration {

   
@Bean
   @ConditionalOnProperty
(prefix "spring.activemq.pool"name "enabled"havingValue "false"matchIfMissing true)
   
public ActiveMQConnectionFactorjmsConnectionFactory(ActiveMQProperties properties) {
      
return new ActiveMQConnectionFactoryFactory(properties)
            .createConnectionFactory(ActiveMQConnectionFactory.
class);
   
}

   
@ConditionalOnClass(PooledConnectionFactory.class)
   
static class PooledConnectionFactoryConfiguration {

      
@Bean(destroyMethod "stop")
      
@ConditionalOnProperty(prefix "spring.activemq.pool"name "enabled"havingValue "true"matchIfMissing false)
      
@ConfigurationProperties(prefix "spring.activemq.pool.configuration")
      
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.getIdleTimeout());
         
pooledConnectionFactory.setExpiryTimeout(pool.getExpiryTimeout());
         return 
pooledConnectionFactory;
      
}

   }

}
 

3.      ActivemqConfig配置修改

@Configuration
public class ActivemqComponent {
    
@Autowired
//    private ActiveMQConnectionFactory connectionFactory;
    
private PooledConnectionFactory connectionFactory;

    

    
@Bean(name "queueListenerFactory")
    
public DefaultJmsListenerContainerFactory queueListenerFactory(){
        DefaultJmsListenerContainerFactory factory = 
new DefaultJmsListenerContainerFactory();
        
factory.setConnectionFactory(connectionFactory);
        
factory.setPubSubDomain(false);
//        factory.setMessageConverter(new SimpleMessageConverter());
        
return factory;
    
}
 

完成以上三点配置后,就可以成功启动了

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有