【问题标题】:Mule Read timed out exceptionMule 读取超时异常
【发布时间】:2015-02-25 18:45:21
【问题描述】:

我有一个 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>

【问题讨论】:

  • 你能分享你的流程配置吗?获取上下文会更容易。
  • 你检查每个http:outbound-endpoint之后收到的状态码吗?
  • 我没有检查它.. 但我猜它应该是 500,因为它落在了 catch 块中.. 但是当我检查数据库时,出站调用证明是成功的.. 所以我没有处理 firstwebservicecall再次在解决业务逻辑的 catch 块中......但从技术上讲,我觉得它是错误的......
  • 如果我理解正确,readTimeOut 发生在您的firstwebservicecallsecondWeberviceCall 成功。对吗?

标签: http mule outbound


【解决方案1】:

您可以在不同的地方配置,从而增加 HTTP 传输的超时:

但这只是进一步推动问题:增加超时可能会暂时解决您的问题,但您仍然面临失败的风险。

为了正确处理它,我认为您应该严格检查每个 HTTP 出站端点之后的响应状态代码,如果状态代码不是您所期望的,则可能使用 filter 来中断流程。

此外,在服务器接收到 HTTP 请求之后、响应返回到 Mule 之前,您很可能会遇到响应超时。在这种情况下,就 Mule 而言,调用失败,必须重试。这意味着远程服务必须是幂等的,即客户端应该能够安全地重试任何失败的操作(或者它认为失败)。

【讨论】:

  • 感谢您的快速回复,正如您所建议的,我检查了 http 状态代码并观察到它在进入 catch-exception-strategy 时有时为 200 次,有时为空,但基于数据库结果检查,在套接字超时异常的情况下,它们都不能证明服务器请求接受是否一致
  • 有什么方法可以检查服务器是否接收到客户端请求以防出现这种读取超时异常???关于服务器端的幂等实现(在我的情况下,它只是另一个调用 web 服务的 esb).. 你是否建议使用 mulesoft.org/docs/site/current/apidocs/org/mule/routing/… 如果是的话,你能给我这个实现的大纲吗谢谢
  • 不确定我是否关注你:你是说即使抛出异常有时也能得到 200?
  • 是的,大卫,我很惊讶在负载测试场景下的 catch 异常策略中看到 Http 状态等于 200 或 null .. 例如:- 如果 5000 条记录在 vm 队列中并以上面通过 vm:inbound 显示,对于 2 或 3 之类的少数记录,我得到了这个读取超时异常,在这 2 或 3 中,很少有 http 状态 200 和其他在 catch 块内为 null
  • 我在我的流程上配置了 ,如上图所示
【解决方案2】:

检查httpconnection中的服务器SO_TIMEOUT,设置为0

检查 - https://www.mulesoft.org/jira/browse/MULE-6331

【讨论】:

  • 谢谢!帮助其他人找到设置。编辑连接器配置,转到 Timings 选项卡,将 Client SO_TIMEOUT 和 Server SO_TIMEOUT 设置为 0。
猜你喜欢
  • 2012-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-06
  • 2012-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多