ActiveMQ“连接池”使用

1. ActiveMQ的连接池

ActiveMQ提供了PoolConnectionFactory、PoolConnection等实现连接池功能,连接池是供对connection、session、producer的“池”,PoolConnectionFactory的类注释说明的原因:

 

类注释代码   收藏代码
  1. <b>NOTE:</b> while this implementation does allow the creation of a collection of active consumers,  
  2. it does not 'pool' consumers. Pooling makes sense for connections, sessions and producers, which  
  3. are expensive to create and can remain idle a minimal cost. Consumers, on the other hand, are usually  
  4. just created at startup and left active, handling incoming messages as they come. When a consumer is  
  5. complete, it is best to close it rather than return it to a pool for later reuse: this is because,  
  6. even if a consumer is idle, ActiveMQ will keep delivering messages to the consumer's prefetch buffer,  
  7. where they'll get held until the consumer is active again.  
  8.   
  9. If you are creating a collection of consumers (for example, for multi-threaded message consumption), you  
  10. might want to consider using a lower prefetch value for each consumer (e.g. 10 or 20), to ensure that  
  11. all messages don't end up going to just one of the consumers. See this FAQ entry for more detail:  
  12. http://activemq.apache.org/i-do-not-receive-messages-in-my-second-consumer.html  

 1)首先connection、session、producer的创建会消耗大量系统资源;

 2)其次consumer有自己的机制,第二段中url中对一个问题进行了说明,其中讲到consumer的一个特性:consumer会获取全部的消息,接收消息的多少可以根据初始化缓存的大小设置,因此在大量消息发送到消费者时,消费者使用类似统一获取、统一消费的方式处理,“池”没有存在的价值。

 

2. 实现原理

 

PoolConnectionFactory

 

  • “池”的存放

 

PoolConnection被一个Map对象存放,ConnectionKey作为该map的key,LinkedList作为连接存放的列表,也就是说获取连接时,首先会根据ConnectionKey获取对应的“小连接池”,再从“小连接池”LinkedList中去连接。

  • 工厂类的参数值

maxmunActive:session的最大活跃值,该参数会通过ConnectionPool的createSession方法如入到Session工程类中(apache-common-pool的GenericObjectPoolFactory);

 

maxConnections:Map的value,LinkedList的大小,即ConnectionPool数量;

 

idleTimeout:线程超时时间,最后使用时间+idleTimeout<当前时间,连接关闭;

 

expiryTimeout:回收时间,连接创建时间+expiryTimeout<当前时间,连接关闭;

 

 

  • 连接创建流程

1)判断工厂是否stop,如果stop,输出日志并返回null;

2)获取ConnectionKey;

3)根据ConnectionKey获取LinkedList;

4)如果LinkedList的大小==maxConnections,获取LinkedList的第一个连接;

5)校验连接,检验失败:a、创建新连接Connection b、通过连接创建ConnectionPool c、将ConnectionPool注入工厂;

6)将ConnectionPool放入LinkedList中;

 

其中创建ConnectionPool设计SessionPool的初始化。

 

3. 样例代码

 

  • 创建连接
Java代码   收藏代码
  1. public class MQPoolUtil {  
  2.   
  3.     private static PooledConnection conn;  
  4.       
  5.     public static void init() {  
  6.         String url = "failover:(tcp://192.168.174.250:61616)?initialReconnectDelay=1000&timeout=3000&startupMaxReconnectAttempts=2";  
  7.         ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(url);  
  8.         try {  
  9.             PooledConnectionFactory poolFactory = new PooledConnectionFactory(factory);  
  10.             conn = (PooledConnection) poolFactory.createConnection();  
  11.             conn.start();  
  12.               
  13.         } catch (JMSException e) {  
  14.             e.printStackTrace();  
  15.         }  
  16.     }  
  17.       
  18.     public static void destroy(){  
  19.         try {  
  20.             if(conn != null) {  
  21.                 conn.close();  
  22.             }  
  23.         } catch (JMSException e) {  
  24.             e.printStackTrace();  
  25.         }  
  26.     }  
  27.   
  28.       
  29.     public static PooledConnection getConn() {  
  30.       
  31.         return conn;  
  32.     }  
  33.   
  34.       
  35.     public static void setConn(PooledConnection conn) {  
  36.       
  37.         MQPoolUtil.conn = conn;  
  38.     }  
  39. }  

 

  • 创建session及producer
Java代码   收藏代码
  1. public class MQProducer extends Thread {  
  2.   
  3.     public void run() {  
  4.   
  5.         String topic = "MQ.TEST";  
  6.         Session session = null;  
  7.         MessageProducer producer = null;  
  8.         try {  
  9.             session = MQPoolUtil.getConn().createSession(false, Session.AUTO_ACKNOWLEDGE);  
  10.   
  11.             Destination destination = session.createTopic(topic);  
  12.               
  13.             System.out.println("session info ->" +session);  
  14.   
  15.             producer = session.createProducer(destination);  
  16.             producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);  
  17.             TextMessage message = session.createTextMessage("hello message!");  
  18.             producer.send(message);  
  19.         } catch (JMSException e) {  
  20.             e.printStackTrace();  
  21.         }  
  22.     }  
  23. }  

 

当执行多次后,从System.out.println中可以看出,sessionid可能是重复的,即缓存中获取了session。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值