簡體   English   中英

ActiveMQ JMSListener

[英]ActiveMQ JMSListener

我是這個主題的新手。 我正在使用JMS偵聽器偵聽包含拆分消息的Active MQ。 我需要聽隊列直到最后一條消息,然后將其一起發送到UI。 我能夠收聽隊列並獲取消息,但是我不知道會有多少拆分消息可用,因此我無法將其全部發送出去。 有什么方法可以使監聽程序執行上述操作? 就像隊列中沒有更多消息一樣,jms監聽器會產生空值嗎? 任何想法或幫助都會非常有幫助。

我正在使用以下代碼使用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("+++++++++++++++++++++++++++++++++++++++++++++++++++++");
}

我可以使用JMS偵聽器獲取隊列信息嗎?

通過jmx,您可以訪問有關目的地的信息,例如,您可以知道消息如何在隊列中掛起。

請注意,如果發送新消息,這可能會改變

長org.apache.activemq.broker.jmx.DestinationViewMBean.getQueueSize()

@MBeanInfo(value =“目標中尚未使用的消息數。可能已分派但未確認。”)

返回此目標中尚未使用的消息數返回:返回此目標中尚未使用的消息數

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

為什么不使用消息,而當沒有收到消息時,您將顯示? 您有下面的方法,如果沒有收到消息,則在超時后返回null。

ActiveMQMessageConsumer.receive(long timeout)拋出JMSException接收在指定的超時間隔內到達的下一條消息。 該調用將阻塞,直到消息到達,超時到期或此消息使用者關閉為止。 零超時永遠不會到期,並且調用會無限期地阻塞。 指定者:接口MessageConsumer中的receive參數:timeout-超時值(以毫秒為單位),從零開始的超時永不過期。 返回:為該消息使用者生成的下一條消息;如果超時到期或此消息使用者同時關閉,則返回null

UPDATE

可能是這樣的:

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 ??
        }
    }
}

因為getQueueSize()返回目標中尚未使用的消息數。 可能已調度但未被確認。

一種解決方案是將用來在您的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