2.)ProgramB有一个监听器来监听从ProgramA创建的消息,处理消息并回复它。但是ProgramB需要与第三方web服务通信,有时需要超过10秒才能回复,这就是我设置消费者监听5000秒(5s)的问题,当然之后会超时。所以消息不会被接收。
我的观察:1.)即使ProgramA完成了读取(还没有回复,在那一刻我试图删除临时队列),但它不能这样做,ProgramB仍然可以写到回复队列,但没有人会读到那个消息(太晚了)。
当我尝试将5s的监听时间改为20s时,问题就解决了,但这是正确的方法吗?
部分代码:
Destination replyQueue = send(jmsUtil, actionDTO);
SalesOrderResponseDTO responseDTO = readReply(jmsUtil, replyQueue, actionDTO);
public Destination send(JmsSessionUtil jmsUtil, SalesOrderActionDTO soDTO) {
try {
utx.begin();
jmsUtil.send(soDTO, null, 0L, 1, Long.parseLong(configBean.getProperty("jms.payrequest.timetolive")), true);
utx.commit();
return jmsUtil.getReplyQueue();
} catch (Exception e) {
try {
utx.rollback();
} catch (Exception e1) {
}
}
return null;
}
public SalesOrderResponseDTO readReply(JmsSessionUtil jmsUtil, Destination replyQueue, SalesOrderActionDTO actionDTO) {
SalesOrderResponseDTO responseDTO = null;
try {
utx.begin();
responseDTO = (SalesOrderResponseDTO) jmsUtil.read(replyQueue);
if (responseDTO != null) {
// fires the response event
SalesOrderResponsePayload eventPayload = new SalesOrderResponsePayload();
eventPayload.setResponseDTO(responseDTO);
responseEvent.fire(eventPayload);
} else { // timeout
((TemporaryQueue) replyQueue).delete();
jmsUtil.dispose();
}
utx.commit();
return responseDTO;
} catch (Exception e) {
try {
utx.rollback();
} catch (Exception e1) {
}
}
return responseDTO;
}
public String send(MessageDTO messageDTO,
JMSQueueEnum resultNotificationQueue, Long parentProcessId,
int JMSPriority, long timeToLive, boolean hasReply)
throws JMSException, InvalidDTOException, NamingException {
try {
// Process optional parameters
messageDTO.setResultNotificationQueue(resultNotificationQueue);
messageDTO.setParentProcessId(parentProcessId);
// Wrap MessageDTO in a JMS ObjectMessage
ObjectMessage msg = MessageDTOHelper.serialize(session, messageDTO);
msg.setJMSType(messageDTO.getClass().getSimpleName());
msg.setStringProperty("DTOType", messageDTO.getClass()
.getSimpleName());
requestProducer = session.createProducer(queue);
if (hasReply) {
replyQueue = session.createTemporaryQueue();
replyConsumer = session.createConsumer(replyQueue);
msg.setJMSReplyTo(replyQueue);
}
if (JMSPriority > -1) {
requestProducer.send(msg, DeliveryMode.PERSISTENT, JMSPriority,
timeToLive);
} else {
// Send the JMS message
requestProducer.send(msg);
}
return msg.getJMSMessageID();
} catch (Exception e) {
}
return null;
}
public MessageDTO read(Destination replyQueue) throws JMSException,
NamingException {
if (replyQueue instanceof Queue) {
Message msg = replyConsumer.receive(20000);
if (msg == null) {
return null;
}
MessageDTO messageDTO = MessageDTOHelper
.deserialize((ObjectMessage) msg);
return messageDTO;
} else {
}
return null;
}
这里的实际问题是您需要同步还是异步通信。
我总是更喜欢异步,从您的问题来看,在您的情况下似乎也不需要同步通信。但是,如果有同步的原因,那么您将被临时队列所困扰--您将不得不指定超时间隔,并且您将面临问题中表达的问题。如果程序A可以等待,则提高超时间隔,尽管这远不是最优的。据我所知,程序B不可能检查A是否还在收听。
在异步通信的情况下,您有(至少)两个JMS选项:
问题内容: 如果我们通过“临时队列”使用JMS请求/答复机制,那么该代码是否可伸缩? 截至目前,我们尚不知道每秒将支持100个请求,还是每秒支持1000个请求。 下面的代码是我正在考虑实现的代码。它以“同步”方式使用JMS。关键部分是创建“消费者”的位置,以指向为此会话创建的“临时队列”。我只是不知道使用这样的临时队列是否是可扩展的设计。 更新: 我遇到了另一种模式,请参阅此博客。 该想法是对发送
我有以下设置: 外部应用程序写入到jms队列 jms队列也是外部的,所以这里不可能进行配置 运行在Glassfish上的现有应用程序,使用ActiveMQ将服务器连接到jms队列 现有的应用程序是一个MessageDriven bean,实现了MessageListener接口(当消息放在队列中时,当前正在处理消息) 新的要求是消息只能在02:00到04:00的时间段内处理 如何最好地限制Mess
我在Weblogic 12c上部署了一个MDB,它从JMS队列(UDQ)读取消息。MDB正在读取消息,但它没有从JMS队列中删除,这导致消息被重复读取。所以,我想知道MDB何时确认JMS队列它成功读取了消息,并且队列应该删除该消息。
我有一个网络应用程序,当用户提交请求时,我们向远程服务发送JMS消息,然后等待回复。(也有异步请求,我们为消息重放等设置了各种细节,所以我们更愿意坚持使用JMS而不是HTTP) 在如何使用JMS实现请求-响应?,ActiveMQ似乎不鼓励每个请求使用临时队列,也不鼓励在JMSCorrelationID上使用选择器的临时消费者,因为这会增加开销。 但是,如果我使用池消费者进行回复,我如何从回复消费者
我通过命名的JMS队列将JMS请求发送到Weblogic 10.3服务器,并通过临时队列接收回复。 客户(裸体): 服务器MDB(消息驱动bean): 问题是第一个服务器回复经常丢失!也就是说,每4-5个回复都以超时结束。当消费者收到第一个答案时,它将继续收到所有剩余的答案,所以问题只出在临时队列创建后通过临时队列发送的第一条消息上。 我的问题是:我是否必须为临时队列设置一些特殊的设置,以便它在创
我有Weblogic 12.1.2和IBM WebSphere MQ Explorer 7.5.0.2。 在Weblogic中,我创建了: JMS服务器 我有一个JAVA程序,可以向这个队列发送消息。 我想使用MQ Explorer来读取来自此队列的消息。我如何设置它?我应该在MQ Explorer中做什么和如何设置,以连接到此队列?有人能给我一个Web链接吗?我找不到任何有用的东西,但也许我想错
问题内容: 我有一个 要求: 我想知道默认的超时时间是多少?以及如何将其设置为3秒或不定秒的特定值? 问题答案: 它没有指定的默认值。该规范根本没有讨论超时。 通常,您可以为承诺实现自己的超时包装器: 如https://github.com/github/fetch/issues/175中所述 (https://github.com/mislav)
我有一个java客户机,它在队列中发送jms消息(“队列请求”)。该消息包含一个int属性(“id”),其中包含唯一的客户端id号。消息正在处理中,然后进入另一个队列(“队列响应”)。如何让客户机等到具有其id的消息在队列中,然后读取它。我曾尝试使用侦听器并实现onMessage,但当收到消息时,我如何停止侦听?