0

我已将 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 的方法。

4

1 回答 1

0

你的问题可能为时已晚。但是,我想分享一些关于这个问题的想法。

该示例仅显示如何从 Oracle AQ 读取到 AMQ。我没有看到关于发送到 Oracle AQ 的逻辑。通过查看您的异常消息,您似乎创建了一个 Oracle AQ 客户端来发送该消息。在这种情况下,它只是打开一个连接并转储消息。如您所见,如果失败,此连接本身将不会保留消息。

所以你可以做几件事:

  1. 继续使用 Oracle AQ 客户端并处理代码中的失败/重试。这意味着如果发送到 Oracle AQ 失败,让代码稍后重试。确保代码每次都关闭连接。

  2. 您已经有一个本地 AMQ 代理。我不熟悉 Oracle AQ。但它可能是一个网络代理模型。请参阅此处并设置 duplex=true。将消息发送到本地 AMQ 代理。然后,如果它无法连接到远程代理,则消息将留在本地,并在重新建立连接时发送出去。

于 2018-05-09T18:59:16.133 回答