我是这个话题的新手。我正在使用JMS侦听器来侦听包含拆分消息的Active MQ。我需要收听队列直到最后一条消息,然后将它们一起发送到UI。我能够收听队列并抓取消息,但我不知道有多少分裂消息可用,所以我无法将它们全部发送出去。有没有办法让听众做上述操作?就像队列中没有可用的消息一样,jms监听器会产生空值吗?任何想法或帮助都会非常有用。
我正在使用以下代码使用JMS侦听器侦听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 Listener获取队列信息吗?
答案 0 :(得分:0)
通过jmx,您可以访问有关目的地的信息,例如,您可以知道消息在队列中的待处理方式。
请注意,如果发送新邮件,则可能会发生这种情况
长 org.apache.activemq.broker.jmx.DestinationViewMBean.getQueueSize()
@MBeanInfo(value =&#34;目的地中的消息数量尚未 消费。可能被派遣但未被承认。&#34;)
返回此目标中尚未发送的消息数 consume返回:返回此目标中的消息数 尚待消费的
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(长时间超时) throws JMSException接收在指定的超时间隔内到达的下一条消息。此调用阻止直到 消息到达,超时到期,或此消息使用者是 关闭。超时为零永不过期,并且调用阻塞 无限期。指定者:在接口MessageConsumer中接收 参数:timeout - 超时值(以毫秒为单位),超时 零永远不会过期。返回:为此生成的下一条消息 消息使用者,如果超时到期或此消息,则为null 消费者同时关闭
<强>更新强>
可能是这样的:
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()
返回了中的邮件数量 尚未消费的目的地。 潜在派遣但是 未确认。强>
一种解决方案是将resumeledgeMode更新为org.apache.activemq.ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE
,以便在您的弹簧DefaultMessageListenerContainer.sessionAcknowledgeModeName
中创建会话,并单独确认每条消息,然后检查大小== 0(大小== 0表示所有消息)被派遣并承认。)