无法从ActiveMQ嵌入式代理同时使用

时间:2015-02-02 22:02:36

标签: java jms activemq

我正在寻找一种向ActiveMQ嵌入式代理发布10条消息的方法,并且在同一个VM上,使用JMS API同时使用它们。

下面的代码有某种竞争,因为有时它会并行消耗2,4,8条消息,并在latch.await调用超时之前挂起。

public final class ActiveMQJMSParallelTest {
    private static final Logger logger = LoggerFactory.getLogger(ActiveMQJMSParallelTest.class);
    private static final int numberOfMessages = 10;

    public static void main(final String[] args) throws Exception {
        final Properties props = new Properties();
        props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
        props.setProperty(Context.PROVIDER_URL, "vm://localhost?broker.persistent=false");
        props.setProperty("queue.parallelQueue", "parallelQueue");
        final Context jndiContext = new InitialContext(props);
        final ConnectionFactory connectionFactory = (ConnectionFactory) jndiContext.lookup("ConnectionFactory");
        final Destination destination = (Destination) jndiContext.lookup("parallelQueue");
        final Connection connection = connectionFactory.createConnection();
        Session session = null;
        try {
            session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
            final MessageProducer producer = session.createProducer(destination);
            for (int i = 0; i < numberOfMessages; i++) {
                final TextMessage message = session.createTextMessage();
                message.setText("This is message " + (i + 1));
                producer.send(message);
                logger.info("Produced message: {}", message);
            }
            session.commit();
        } finally {
            if (session != null)
                session.close();
        }

        final CountDownLatch latch = new CountDownLatch(numberOfMessages);
        final ExecutorService pool = Executors.newFixedThreadPool(numberOfMessages);
        for (int i = 0; i < numberOfMessages; i++) {
            pool.submit(new Runnable() {
                @Override public void run() {
                    try {
                        final Connection connection = connectionFactory.createConnection();
                        connection.start();
                        final Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
                        final Queue destination = session.createQueue("parallelQueue");
                        final MessageConsumer consumer = session.createConsumer(destination);
                        final Message received = consumer.receive();
                        logger.info("Consuming message: {}", received);
                        latch.countDown();
                        latch.await(1, TimeUnit.MINUTES);
                        logger.info("Consumed message: {}", received);
                        session.close();
                        connection.close();
                    } catch(Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        latch.await(10, TimeUnit.MINUTES);
        jndiContext.close();
    }
}

有人可以为此任务召唤工作代码吗?

1 个答案:

答案 0 :(得分:1)

如果你想确保每个消费者有机会一次抓取一条消息,那么你应该使用预取值为零,这样代理就不会尝试为第一个消费者分配预取限制,所以当他们到达时

了解预取如何在documentation页面上运行。