AMQ + Oracle AQ: потерянное сообщение при неудачном соединении
Я настроил AMQ для получения и отправки сообщений из Oracle AQ, как описано здесь http://activemq.apache.org/jms-bridge-with-oracle-aq.html
AMQ создает и удерживает соединение для получения сообщений от Oracle AQ - это правильно. Однако новое соединение создавалось и уничтожалось каждый раз, когда AMQ отправляет сообщение в Oracle AQ. Иногда из-за проблем с сетью или перегрузки Oracle я получаю исключение:
org.apache.camel.RuntimeCamelException: org.springframework.jms.UncategorizedJmsException: Uncategorized exception occured during JMS processing; nested exception is oracle.jms.AQjmsException: IO Error: Socket read timed out
at org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1344)
at org.apache.camel.component.jms.EndpointMessageListener$EndpointMessageListenerAsyncCallback.done(EndpointMessageListener.java:186)
at org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:107)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:562)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:500)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:468)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1103)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1095)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:992)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: org.springframework.jms.UncategorizedJmsException: Uncategorized exception occured during JMS processing; nested exception is oracle.jms.AQjmsException: IO Error: Socket read timed out
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:316)
at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:168)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:469)
at org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemplate.send(JmsConfiguration.java:226)
at org.apache.camel.component.jms.JmsProducer.doSend(JmsProducer.java:415)
at org.apache.camel.component.jms.JmsProducer.processInOnly(JmsProducer.java:369)
at org.apache.camel.component.jms.JmsProducer.process(JmsProducer.java:145)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:110)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:398)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:105)
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:87)
at org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:103)
... 11 more
Caused by: oracle.jms.AQjmsException: IO Error: Socket read timed out
at oracle.jms.AQjmsDBConnMgr.checkForSecurityException(AQjmsDBConnMgr.java:939)
at oracle.jms.AQjmsDBConnMgr.getConnection(AQjmsDBConnMgr.java:617)
at oracle.jms.AQjmsDBConnMgr.<init>(AQjmsDBConnMgr.java:251)
at oracle.jms.AQjmsConnection.<init>(AQjmsConnection.java:185)
at oracle.jms.AQjmsConnectionFactory.createConnection(AQjmsConnectionFactory.java:583)
at org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter.doCreateConnection(UserCredentialsConnectionFactoryAdapter.java:175)
at org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter.createConnection(UserCredentialsConnectionFactoryAdapter.java:150)
at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:184)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:456)
... 23 more
Caused by: java.sql.SQLRecoverableException: IO Error: Socket read timed out
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:458)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:546)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:236)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:521)
at java.sql.DriverManager.getConnection(DriverManager.java:571)
at java.sql.DriverManager.getConnection(DriverManager.java:187)
at oracle.jms.AQjmsDBConnMgr.getConnection(AQjmsDBConnMgr.java:579)
... 30 more
Caused by: oracle.net.ns.NetException: Socket read timed out
at oracle.net.ns.Packet.receive(Packet.java:339)
at oracle.net.ns.NSProtocol.connect(NSProtocol.java:296)
at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1102)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:320)
... 37 more
И после этого сообщение теряется.
В связи с тем, что новая операция подключения довольно тяжелая, я попытался настроить org.springframework.jms.core.JmsTemplate для использования подключений в пуле, как описано здесь http://activemq.apache.org/spring-support.html Но это не помогло Новые связи все еще создаются.
Пожалуйста, посоветуйте метод, который помог бы мне не терять сообщения от AMQ к Oracle AQ.
1 ответ
Это может быть слишком поздно для вашего вопроса. Тем не менее, я хочу поделиться некоторыми мыслями об этой проблеме.
В примере показано только, как читать из Oracle AQ в AMQ. Я не видел логики отправки в Oracle AQ. При просмотре сообщения об исключении вы, похоже, создали клиента Oracle AQ для отправки сообщения. В этом случае он просто открывает соединение и выдает сообщение. Как видите, в случае сбоя само соединение не сохранит сообщение.
Итак, пара вещей, которые вы можете сделать:
Продолжайте использовать клиент Oracle AQ и обработайте ошибку / повтор в вашем коде. Это означает, что если отправка в Oracle AQ не удалась, позвольте коду повторить попытку позже. Убедитесь, что код закрывает соединение каждый раз.
У вас уже есть местный брокер AMQ. Я не знаком с Oracle AQ. Но это может быть модель сетевого брокера. Обратитесь сюда и установите duplex=true. Отправьте сообщение вашему местному брокеру AMQ. Затем, если ему не удалось подключиться к удаленному посреднику, сообщение останется локально и будет отправлено после восстановления соединения.