[英]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.