0

I facing problems with my JMS environment.

I created a JMSTemplate, and it uses a ActiveMQSslConnectionFactory (for security purposes).

Sometimes my server can be offline, or the host can be unreachable. In this cases my JMSTemplate cannot connect to the host and my message will not be delivered due to this exception:

org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: Could not connect to broker URL: ssl://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect

There is any resource/configuration to the JMSTemplate or in the ConnectionFactory to persist this unsent messages and resend them when the connection is reestablished?

Beto Neto
  • 3,962
  • 7
  • 47
  • 81
  • 1
    Some JMS providers (Fiorano comes to mind) have a specific feature to store messages locally (on the producer) in the case the broker is unreachable at the expense of potentially loosing those messages if the node fails completely. ActiveMQ doesn't provide this feature. You could do something to catch those failures and keep the messages in memory (or saved somewhere DB/disk?) until the connection is re-established, but it might be better to spend the time to set up an HA ActiveMQ cluster. – Augusto Jul 05 '18 at 14:24
  • @Augusto solved by https://stackoverflow.com/questions/51180370/spring-jmstemplate-unsent-messages-when-connection-refused#comment89376871_51192894 – Beto Neto Jul 05 '18 at 18:13

2 Answers2

1

Messaging servers such as ActiveMQ is to be considered critical infrastructure, similar to databases and should be setup with multi server/HA setup avoid server downtime at all costs. However there are some ways to mitigate the case of downtime. Like buffering internal events in a BlockingQueue or similar. That scenario will still cause message loss if the application is restarted during ActiveMQ downtime. To be really sure no data is lost, each event must be persisted into a database (that might also be down) or into some embedded ActiveMQ, tightly connected to the application.

A working approach might be to configure an application bound (embedded) ActiveMQ and have the application write to it, then setup a "Network of brokers" to the remote ActiveMQ. That way, the application will always read/write to the local ActiveMQ and messages will flow when both instances are online. This will only work as long there is free diskspace locally, so you still need some idea what to do when shit hits the fan.

Petter Nordlander
  • 22,053
  • 5
  • 50
  • 84
0

Persist them where?

No; there is no such mechanism; you can wrap the JmsTemplate calls in a RetryTemplate from spring-retry but if you want to persist failures somewhere, you will need to implement that.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • I suspected that. I have created a `Queue` using `Berkeley-DB` to persist (as json) on disk the messages who wasn't sent. Now my bean always add the messages to this queue and a async task consumes them. – Beto Neto Jul 05 '18 at 18:12