J'ai actuellement un problème avec l'approche requête synchrone jms/réponse, voici ce qui se passe:JMS synchrone demande/réponse en utilisant la file d'attente temporaire timed out lecture
1.) ProgramA créer un message jms, une file d'attente temporaire et définissez-le comme une réponse à. 2.12 ProgramB a un écouteur pour le message créé à partir de ProgramA, traite le message et y répond. Mais ProgramB doit communiquer avec un service Web tiers qui prend parfois plus de 10 secondes pour répondre, et c'est le problème que je mets le consommateur à écouter pour 5000 (5s) et bien sûr, il va expirer après. Donc, le message n'est pas reçu.
Mon observation: 1.) Même si ProgramA est en train de lire (pas de réponse pour le moment, j'essaye de supprimer la file d'attente temporaire). Ce n'est pas possible et ProgramB était encore capable d'écrire dans la file d'attente de réponse, mais personne ne va lire ce message (trop tard).
Lorsque j'essaie de changer le temps d'écoute de 5s à 20s, le problème a été résolu, mais est-ce la bonne approche?
Est-il également possible que ProgramB ne tente pas d'écrire dans la file d'attente lorsque ProgramA a arrêté la lecture?
codes partiels:
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;
}
Salut @Miljen, malheureusement je suis coincé avec synchrone car la source de la requête doit afficher la réponse autant que possible.Je suis juste préoccupé par le fait que je dois augmenter le temps d'attente parce que la 3ème partie pourrait même répondre dans une minute et cela ralentirait le système quand j'ai des centaines d'utilisateurs simultanés. – czetsuya
@czetsuya Je comprends. Cependant, vous ne bénéficierez toujours pas du maintien du programme A dans un état bloqué. Ma suggestion: A envoie le message avec un ID de corrélation, affiche la barre de progression (ou quelque chose de similaire) et termine. Lorsque le programme B répond avec l'ID de corrélation exacte, activez le programme A, supprimez la barre de progression et affichez la réponse. Sinon, vous risquez de manquer de ressources, car des centaines d'utilisateurs simultanés signifieraient des centaines de threads bloqués et en attente. –