当客户端在activemq中的空闲时间时删除特定队列

时间:2014-07-23 08:18:14

标签: java activemq

我希望在使用者在activemq中停机时删除特定队列。消费者可用时间我不想发送队列消息。给我一些建议。谢谢。

这是我的发布商类

public class MessageHandler implements MessageListener {
    private static String url = "tcp://localhost:61616";
    private Session session;

    private MessageProducer producer;
    private MessageConsumer consumer;
    private Connection connection;
    private Map<String, String> messageStatus = new HashMap<String, String>();
    public void setup(String systemCode, String funCode, boolean synchronous) {
        try {
            ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
            if(synchronous) {
                connection = connectionFactory.createConnection();
                connection.start();
                session = connection.createSession(false, Session.SESSION_TRANSACTED);
            } else {
                connection = connectionFactory.createConnection();
                connection.start();
                session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            }
            Destination requestQueue = session.createQueue(systemCode + "-" + funCode + "-request");
            producer = session.createProducer(requestQueue);
            Destination responseQueue = session.createQueue(systemCode + "-" + funCode + "-response");
            consumer = session.createConsumer(responseQueue);
            consumer.setMessageListener(this);
        } catch(JMSException e) {
            throw new RuntimeException("Failed to initialize MessageHandler", e);
        }
    }

    public String sendMessage(String parameter) {
        String response = null;
        try {
            TextMessage message = session.createTextMessage(parameter);
            String messageId = UUID.randomUUID().toString();
            message.setJMSCorrelationID(messageId);
            producer.send(message);
            boolean carryon = true; 
            long start = System.currentTimeMillis();
            long end = start + 10 * 1000;
            while (System.currentTimeMillis() < end && carryon) {
                if(checkStatus(messageId)) {
                    carryon = false;
                }
            }
            response = getMessage(messageId);
            stop();
        } catch(JMSException e) {
            try {
                stop();
            } catch (JMSException e1) {
                throw new RuntimeException("Failed to send Message", e);
            }
            throw new RuntimeException("Failed to send Message", e);
        } 
        return response;
    }

    private String getMessage(String correlationId) {
        synchronized (this) {
            if (messageStatus.containsKey(correlationId)) {
                String status = messageStatus.get(correlationId);
                messageStatus.remove(correlationId);
                return status;
            } else {
                return null;
            }
        }
    }

    private boolean checkStatus(String messageId) {
        return messageStatus.containsKey(messageId);
    }

    public void onMessage(Message message) {
        synchronized (this) {
            try {
                if (message instanceof TextMessage) {
                    String originalMessageId = message.getJMSCorrelationID();
                    String responseText = ((TextMessage) message).getText();
                    messageStatus.put(originalMessageId, responseText);
                }
            } catch (JMSException e) {
                throw new RuntimeException("Failed to receipt Message", e);
            }
        }
    }

    public void stop() throws JMSException {
        session.close();
        connection.close();
    }

    public static void main(String[] args) throws Exception {
        System.out.println("Caller Client.....");
        MessageHandler handler = new MessageHandler();
        handler.setup("P001", "FUC0001", true);
        String response = handler.sendMessage("xxxxxx");
        System.out.println(response);
    }   
}

当我使用Session.SESSION_TRANSACTED时,我无法从我的监听器类订阅并且队列中没有消息。我的目标是当没有消费者时,我想删除队列,如果有任何消费者,他们可以订阅。

2 个答案:

答案 0 :(得分:0)

交易会话的第一个会话创建错误,会话交易标志需要设置为true,你的设置为false。

听起来您想要删除非活动目的地,您可以通过名为gcInactiveDestinations的ActiveMQ中的目标策略来执行此操作。使用该选项,将删除在没有注册消费者的情况下空闲一段时间的目的地。您还可以使用来自经纪人的advisory消息来了解消费者的来来往往。

目前还不是很清楚你想要完成什么,所以这是我能给你的最好的信息,直到你澄清你想要解决的问题为止。

答案 1 :(得分:0)

我的要求

对于同步过程

客户端将消息发送到服务器,但MessageLestener未激活/关闭,我想从队列中删除此特定消息。

如何使用messageid从队列中删除特定邮件?

我也喜欢你的问题,我提供了可恢复的功能。您只需要传递MessageIdQueue名称即可。对我来说没关系。

private void deleteMessage(String messageId, String queueName) {
    try {
         JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi");
         JMXConnector jmxc = JMXConnectorFactory.connect(url);
         MBeanServerConnection conn = jmxc.getMBeanServerConnection();
         ObjectName name = new ObjectName("org.apache.activemq:type=Broker,brokerName=localhost");
         BrokerViewMBean proxy = (BrokerViewMBean)MBeanServerInvocationHandler.newProxyInstance(conn, name, BrokerViewMBean.class, true);
         for (ObjectName queue : proxy.getQueues()) {  
            QueueViewMBean queueBean = (QueueViewMBean) MBeanServerInvocationHandler.newProxyInstance(conn, queue, QueueViewMBean.class, true);
            if(queueBean.getName().equals(queueName)) {
                System.out.println("Deleted : " + messageId);
                queueBean.removeMessage(messageId);
                return;
            }
         }
    } catch(Exception e) {
        e.printStackTrace();
    }
}

我使用activemq-all-5.8.0.jar

相关问题