我有一个esb,我从中进行了一次web服务调用,大部分时间都可以正常工作,但有时我得到以下异常
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
奇怪的是,在我得到这个例外之后,有时候http出站呼叫仍然成功,有时候没有成功
为什么这不一致?
是否有可能mule http连接器上的某些配置可以帮助此异常情况一致地运行?
我要问的是......如何在抛出读取超时异常后停止处理http出站请求?
流程如下图所示
<queued-asynchronous-processing-strategy name="allow2Threads" maxThreads="2"/>
<flow name="TestFlow" processingStrategy="allow2Threads">
<vm:inbound-endpoint path="performWebserviceLogic" exchange-pattern="one-way" />
.... some transformation logic
....
<http:outbound-endpoint address="http://localhost:8080/firstwebservicecall" responseTimeout="65000" exchange-pattern="request-response"/>
....
.... some transformation logic on response...
<http:outbound-endpoint address="http://localhost:8080/secondWeberviceCall" responseTimeout="20000" exchange-pattern="request-response"/>
......some transformation logic on response...
<catch-exception-strategy>
<choice>
<when expression="#[groovy:message.getExceptionPayload().getRootException.getMessage().equals('Read timed out') and message.getSessionProperty('typeOfCall').equals('firstWeberviceCall')]">
.... unreliable ...result... as firstWeberviceCall may succeed even after the control comes here
and if we process http://localhost:8080/firstwebservicecall .. the transaction takes place twice... as already it succeeded above even after an exception is thrown
</when>
<when expression="#[groovy:message.getExceptionPayload().getRootException.getMessage().equals('Read timed out') and message.getSessionProperty('typeOfCall').equals('secondWeberviceCall')]">
..... reliable ... if control comes here and if we process http://localhost:8080/secondWeberviceCall .. the transaction takes place only once
</when>
<when expression="#[groovy:message.getExceptionPayload().getRootException.getMessage().equals('Connect timed out') and message.getSessionProperty('typeOfCall').equals('firstWeberviceCall')]">
....reliable
</when>
<when expression="#[groovy:message.getExceptionPayload().getRootException.getMessage().equals('Connect timed out') and message.getSessionProperty('typeOfCall').equals('secondWeberviceCall')]">
....reliable
</when>
</choice>
</catch-exception-strategy>
</flow>
答案 0 :(得分:1)
您可以配置,从而增加HTTP传输在不同位置的超时:
这只会进一步解决问题:增加超时可能会暂时解决您的问题,但您仍然会遇到失败。
为了正确处理它,我认为你应该在每个HTTP出站端点之后严格检查响应状态代码,如果状态代码不符合预期,可以使用filter
来打破流程。
此外,在服务器收到HTTP请求之后以及响应返回Mule之前,您可以获得响应超时。在这种情况下,就Mule而言,呼叫失败并且必须重试。这意味着远程服务必须是幂等的,即客户端应该能够安全地重试任何失败的操作(或者它认为已经失败)。
答案 1 :(得分:1)
检查httpconnection中的服务器SO_TIMEOUT,将其设置为0