简体   繁体   English

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

[英]Delete specific queue when client's idle time in activemq

I want to delete a specific queue when consumer's down time in activemq. 当消费者在activemq停机时,我想删除特定的队列。 I don't want to send queue message when consumer available time.Give me some suggestions.Thanks in advance. 我不想在消费者有空时发送队列消息。给我一些建议。

This is my publisher class 这是我的出版商课程

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);
    }   
}

When i use Session.SESSION_TRANSACTED , i can't subscribe from my listener class and there is no message in queue.My goal is when there is no consumer,i want to delete queue and if there any consumer,they can subscribe. 当我使用Session.SESSION_TRANSACTED ,我无法从我的侦听器类订阅,并且队列中没有消息。我的目标是当没有使用方时,我想要删除队列,如果有任何使用方,则可以订阅。

First of the session creation for transacted sessions is wrong, the session transacted flag needs to be set to true, yours is false. 首先为事务处理会话创建会话是错误的,需要将会话事务处理标志设置为true,而将您的事务处理标志设置为false。

It sounds like you want to delete inactive destinations which you can do via a destination policy in ActiveMQ called gcInactiveDestinations . 听起来您想删除不活动的目标,可以通过ActiveMQ中名为gcInactiveDestinations的目标策略来执行此操作 With that option the destination that sits empty for some time with no consumers registered will be deleted. 使用该选项,将删除在一段时间内未注册任何使用者的目的地。 You can also use advisory messages from the broker to learn about consumers coming and going. 您还可以使用来自代理的咨询消息来了解来来去去的消费者。

It's still not really clear what you are trying to accomplish so this is the best info I can give you until you clarify the problem you are trying to solve. 仍然不清楚您要完成的工作,因此这是我可以提供给您的最佳信息,直到您阐明要解决的问题为止。

My Requirement 我的要求

For Synchronous Process 对于同步过程

Client send the message to the server, but MessageLestener is not active/down, I want to remove this specific message from the queue. 客户端将消息发送到服务器,但是MessageLestener没有处于活动状态/关闭状态,我想从队列中删除此特定消息。

How to delete specific message from queue by using messageid? 如何使用messageid从队列中删除特定消息?

I also have like your problem, I provide the resuable function. 我也喜欢您的问题,我提供可恢复的功能。 You just need to pass MessageId and Queue name. 您只需要传递MessageIdQueue名称。 It is ok for me. 对我来说没关系。

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();
    }
}

I use activemq-all-5.8.0.jar . 我使用activemq-all-5.8.0.jar

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM