简体   繁体   English

ActiveMQ JMSListener

[英]ActiveMQ JMSListener

I'm new to this topic. 我是这个主题的新手。 I'm Using JMS listener to listen to an Active MQ which contains split messages. 我正在使用JMS侦听器侦听包含拆分消息的Active MQ。 I need to listen to the queue till last message and then send it to UI all together. 我需要听队列直到最后一条消息,然后将其一起发送到UI。 I'm able to listen to the queue and grab messages but I do not know how many split messages will be available so i'm not able to send it all together. 我能够收听队列并获取消息,但是我不知道会有多少拆分消息可用,因此我无法将其全部发送出去。 Is there any way to make listener to do the above operation? 有什么方法可以使监听程序执行上述操作? Like if there is no more messages available in queue, will jms listener produces a null value? 就像队列中没有更多消息一样,jms监听器会产生空值吗? Any idea or help will be really helpful. 任何想法或帮助都会非常有帮助。

I'm Using the below code to listen to Queue using JMS Listener. 我正在使用以下代码使用JMS Listener来监听Queue。

 private static final String ORDER_RESPONSE_QUEUE = "mail-response-queue";

@JmsListener(destination = ORDER_RESPONSE_QUEUE)
public void receiveMessage(final Message<InventoryResponse> message) throws JMSException {
    LOG.info("+++++++++++++++++++++++++++++++++++++++++++++++++++++");
    MessageHeaders headers =  message.getHeaders();
    LOG.info("Application : headers received : {}", headers);

    InventoryResponse response = message.getPayload();
    LOG.info("Application : response received : {}",response);  
    LOG.info("+++++++++++++++++++++++++++++++++++++++++++++++++++++");
}

Can i get Queue information using JMS Listener? 我可以使用JMS侦听器获取队列信息吗?

by jmx you have access to informations about destinations, like this for example you can know how messages are pending in a Queue. 通过jmx,您可以访问有关目的地的信息,例如,您可以知道消息如何在队列中挂起。

Note that this can change if new messages are sent 请注意,如果发送新消息,这可能会改变

long org.apache.activemq.broker.jmx.DestinationViewMBean.getQueueSize() 长org.apache.activemq.broker.jmx.DestinationViewMBean.getQueueSize()

@MBeanInfo(value="Number of messages in the destination which are yet to be consumed. Potentially dispatched but unacknowledged.") @MBeanInfo(value =“目标中尚未使用的消息数。可能已分派但未确认。”)

Returns the number of messages in this destination which are yet to be consumed Returns:Returns the number of messages in this destination which are yet to be consumed 返回此目标中尚未使用的消息数返回:返回此目标中尚未使用的消息数

import java.util.HashMap;
import java.util.Map;

import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

import org.apache.activemq.broker.jmx.BrokerViewMBean;
import org.apache.activemq.broker.jmx.QueueViewMBean;

public class JMXGetDestinationInfos {

    public static void main(String[] args) throws Exception {
        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://host:1099/jmxrmi");
        Map<String, String[]> env = new HashMap<>();
        String[] creds = {"admin", "activemq"};
        env.put(JMXConnector.CREDENTIALS, creds);
        JMXConnector jmxc = JMXConnectorFactory.connect(url, env);
        MBeanServerConnection conn = jmxc.getMBeanServerConnection();

        ObjectName activeMq = new ObjectName("org.apache.activemq:type=Broker,brokerName=localhost");

        BrokerViewMBean mbean = MBeanServerInvocationHandler.newProxyInstance(conn, activeMq, BrokerViewMBean.class,
                true);
        for (ObjectName name : mbean.getQueues()) {
            if (("Destination".equals(name.getKeyProperty("destinationName")))) {
                QueueViewMBean queueMbean = MBeanServerInvocationHandler.newProxyInstance(conn, name,
                        QueueViewMBean.class, true);
                System.out.println(queueMbean.getQueueSize());
            }
        }
    }
}

Why not consuming messages and when there is no messages received you display ?? 为什么不使用消息,而当没有收到消息时,您将显示? You have method below which returns null after a timeout if there no messages received. 您有下面的方法,如果没有收到消息,则在超时后返回null。

ActiveMQMessageConsumer.receive(long timeout) throws JMSException Receives the next message that arrives within the specified timeout interval. ActiveMQMessageConsumer.receive(long timeout)抛出JMSException接收在指定的超时间隔内到达的下一条消息。 This call blocks until a message arrives, the timeout expires, or this message consumer is closed. 该调用将阻塞,直到消息到达,超时到期或此消息使用者关闭为止。 A timeout of zero never expires, and the call blocks indefinitely. 零超时永远不会到期,并且调用会无限期地阻塞。 Specified by: receive in interface MessageConsumer Parameters: timeout - the timeout value (in milliseconds), a time out of zero never expires. 指定者:接口MessageConsumer中的receive参数:timeout-超时值(以毫秒为单位),从零开始的超时永不过期。 Returns: the next message produced for this message consumer, or null if the timeout expires or this message consumer is concurrently closed 返回:为该消息使用者生成的下一条消息;如果超时到期或此消息使用者同时关闭,则返回null

UPDATE UPDATE

may be like this : 可能是这样的:

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;

import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

import org.apache.activemq.broker.jmx.BrokerViewMBean;
import org.apache.activemq.broker.jmx.QueueViewMBean;

public class JMXGetDestinationInfos {

    private QueueViewMBean queueMbean;

    {
        try {
            JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://host:1099/jmxrmi");
            Map<String, String[]> env = new HashMap<>();
            String[] creds = { "admin", "activemq" };
            env.put(JMXConnector.CREDENTIALS, creds);
            JMXConnector jmxc = JMXConnectorFactory.connect(url, env);
            MBeanServerConnection conn = jmxc.getMBeanServerConnection();

            ObjectName activeMq = new ObjectName("org.apache.activemq:type=Broker,brokerName=localhost");

            BrokerViewMBean mbean = MBeanServerInvocationHandler.newProxyInstance(conn, activeMq, BrokerViewMBean.class,
                    true);
            for (ObjectName name : mbean.getQueues()) {
                if (("Destination".equals(name.getKeyProperty("destinationName")))) {
                    queueMbean = MBeanServerInvocationHandler.newProxyInstance(conn, name, QueueViewMBean.class, true);
                    System.out.println(queueMbean.getQueueSize());
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @JmsListener(destination = ORDER_RESPONSE_QUEUE)
    public void receiveMessage(final Message<InventoryResponse> message, javax.jms.Message amqMessage) throws JMSException {
        LOG.info("+++++++++++++++++++++++++++++++++++++++++++++++++++++");
        MessageHeaders headers =  message.getHeaders();
        LOG.info("Application : headers received : {}", headers);

        InventoryResponse response = message.getPayload();
        LOG.info("Application : response received : {}",response);  
        LOG.info("+++++++++++++++++++++++++++++++++++++++++++++++++++++");
        //queueMbean.getQueueSize()  is real time, each call return the real size
        ((org.apache.activemq.command.ActiveMQMessage) amqMessage ).acknowledge();
        if(queueMbean != null && queueMbean.getQueueSize() == 0){
            //display messages ??
        }
    }
}

because getQueueSize() return the umber of messages in the destination which are yet to be consumed. 因为getQueueSize()返回目标中尚未使用的消息数。 Potentially dispatched but unacknowledged. 可能已调度但未被确认。

One solution is to update the acknowledgeMode to org.apache.activemq.ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE for sessions creation in your spring DefaultMessageListenerContainer.sessionAcknowledgeModeName and acknowledge each message individually and check after that if the size == 0 (size == 0 means all messages are dispatched and acknowledged). 一种解决方案是将用来在您的spring DefaultMessageListenerContainer.sessionAcknowledgeModeName创建会话的形式的org.apache.activemq.ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE更新为org.apache.activemq.ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE ,并分别确认每个消息,然后检查大小== 0(大小== 0表示所有消息都是派遣并确认)。

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

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