The ActiveMQ pooling library provides a solution for three common pooling scenarios when using the JMS API:
- Pooling of
Connection
objects for applications that either need to share a single connection or a set of connections among code that would otherwise result in many connections being opened and closed over time. - Pooling of
Session
objects for a single connection for an application that would otherwise create and destroy large numbers of sessions over time. - Pooling of
MessageProducer
objects for applications that either need a large number ofMessageProducer
instances or that create and destroy manyMessageProducer
instances over time.
ActiveMQ.Advisory.Producer.Queue.XXXX
因为频繁的create或者close 这三个元素会导致产生许多的Advisory Messages
All of this may sound complicated but it's really not that bad. The classes in the pooling library behave pretty much the same as their pure JMS client counterparts. What you need to keep in mind is that when you close a PooledSession
instance you close its cached producer, and when you close a PooledConnection
instance you close all those PooledSession
instances. The code that uses these types needs to ensure that it's taking advantage of the properties of the pooled library in a way that makes sense, otherwise it won't perform any better than the non-pooled JMS client code and could perform worse in some cases.
参考文献
https://www.safaribooksonline.com/library/view/instant-apache-activemq/9781782169413/ch01s11.html
实例:
需要引入两个 pool jar分别为:activemq-jms-pool-5.10.0.jar,activemq-pool-5.10.0.jar
package org.apache.activemq.recipes;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.pool.PooledConnectionFactory;
public class ConnectionPoolApp {
private final String connectionUri = "tcp://localhost:61616";
private ActiveMQConnectionFactory connectionFactory;
private PooledConnectionFactory pooledFactory;
private CountDownLatch done;
private BrokerService broker;
private final int NUM_SENDERS = 20000;
private final int NUM_SENDS = 100;
public void before() throws Exception {
/***
broker = new BrokerService();
broker.setPersistent(false);
broker.addConnector("tcp://0.0.0.0:61616");
broker.start();
*****/
connectionFactory = new ActiveMQConnectionFactory(connectionUri);
pooledFactory = new PooledConnectionFactory(connectionFactory);
//pooledFactory.setMaxConnections(11);
}
public void after() throws Exception {
// pooledFactory.clear();
// broker.stop();
}
public void run() throws Exception {
/*****
System.out.print("Non-Pooled test took: ");
long nonPooledTime = runPerformanceTest(connectionFactory);
System.out.println(TimeUnit.MILLISECONDS.toSeconds(nonPooledTime) + " seconds");
****/
System.out.print("Pooled test took: ");
long pooledTime = runPerformanceTest(pooledFactory);
System.out.println(TimeUnit.MILLISECONDS.toSeconds(pooledTime) + " seconds");
}
class Sender implements Runnable {
private final Connection connection;
Sender(Connection connection) {
this.connection = connection;
}
public void run() {
try {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
for (int i = 0; i < NUM_SENDS; i++) {
Destination destination = session.createQueue("TEST");
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
producer.send(session.createMessage());
producer.close();
}
Thread.sleep(5000);
session.close();
session=null;
connection.close();
} catch(Exception ex) {
System.out.println("Run caught exception: " + ex.getMessage());
} finally {
done.countDown();
}
}
}
private long runPerformanceTest(ConnectionFactory factory) throws Exception {
this.done = new CountDownLatch(NUM_SENDERS);
ExecutorService service = Executors.newFixedThreadPool(10);
long startTime = System.currentTimeMillis();
for (int i = 0; i < NUM_SENDERS; ++i) {
Connection connection=factory.createConnection();
service.execute(new Sender(connection));
}
done.await();
long endTime = System.currentTimeMillis();
service.shutdown();
return endTime - startTime;
}
public static void main(String[] args) {
ConnectionPoolApp example = new ConnectionPoolApp();
System.out.print("\n\n\n");
System.out.println("Starting Pooled Connection example now...");
try {
example.before();
example.run();
example.after();
} catch (Exception e) {
System.out.println("Caught an exception during the example: " + e.getMessage());
}
System.out.println("Finished running the Pooled Connection example.");
System.out.print("\n\n\n");
}
}