You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mule 4中使用on-error-continue避免JMS空队列错误日志

解决方案

方案一:修改错误处理器,捕获JMS超时错误并静默终止流程

问题根源是JMS Consume组件在队列无消息超时后会抛出JMS:TIMEOUT错误,当前错误处理器设置了logException="true",导致错误日志被打印。只需针对该错误类型调整错误处理逻辑:

  1. 修改错误处理器,指定仅捕获JMS:TIMEOUT错误,关闭错误日志打印,同时终止流程避免后续组件执行
  2. 移除无效的otherwise分支(因为超时会直接抛错,不会走到该分支)

修改后的完整配置:

<flow name="docusign-message-reprocessing-reports-subflow" doc:id="f3ffe923-ee3e-4e0d-8a29-ec874b9755d7" >
    <scheduler doc:name="Scheduler" doc:id="ff715c36-be3e-4f79-bdc9-db7934c75985" >
        <scheduling-strategy >
            <fixed-frequency timeUnit="HOURS" frequency="3" startDelay="1"/>
        </scheduling-strategy>
    </scheduler>
    <logger level="INFO" doc:name="Logger" doc:id="66ef28f0-c4a6-4bec-b824-a51ce7e8ea79" message="@@@@ ---&gt; scheduler triggered"/>
    <jms:consume doc:name="Consume" doc:id="e63155ec-7563-4409-bd83-c66e6e1c792a" config-ref="AMQ-DocuSign-Connector" destination="#[Mule::p('amq.docusign.reports.bqueue')]" maximumWaitUnit="SECONDS" maximumWait="10">
        <jms:consumer-type>
            <jms:queue-consumer />
        </jms:consumer-type>
    </jms:consume>
    <logger level="INFO" doc:name="Logger" doc:id="47cd3399-a84d-476e-b065-b58c6d94079d" message="printing payload #[payload]"/>
    <choice doc:name="Choice" doc:id="ea7cbccb-6b47-456b-a2cb-c67561b53917">
        <when expression="#[!isEmpty(payload)]">
            <logger level="INFO" doc:name="Logger" doc:id="b8c49215-383f-45e3-aaf3-2b9511a53828" message="#[&quot;Moving messages from DLQ&quot; ++ Mule::p('amq.docusign.reports.bqueue')  as String ++   &quot;to&quot; ++ Mule::p('amq.docusign.reports.topic') as String]" />
            <jms:publish doc:name="Publish" doc:id="44425d09-4ced-4a9d-a1c8-9c6259a2b6c9" destination="${amq.docusign.reports.topic}" config-ref="AMQ-DocuSign-Connector" destinationType="TOPIC" />            
        </when>
    </choice>
    <error-handler >
        <!-- 专门处理JMS超时错误,不打印错误日志,直接终止流程 -->
        <on-error-continue enableNotifications="false" logException="false" doc:name="On Error Continue" doc:id="timeout-handler" type="JMS:TIMEOUT">
            <!-- 可选:保留INFO级别的无消息提示,不需要可删除 -->
            <logger level="INFO" doc:name="Logger" doc:id="no-message-log" message="No messages found in queue #[Mule::p('amq.docusign.reports.bqueue')]"/>
            <stop doc:name="Stop" doc:id="stop-flow"/>
        </on-error-continue>
        <!-- 处理其他类型的错误,保留原日志逻辑 -->
        <on-error-continue enableNotifications="true" logException="true" doc:name="On Error Continue" doc:id="general-error-handler" >
            <logger level="ERROR" doc:name="Logger" doc:id="error-log" message="Unexpected error: #[error.message]"/>
        </on-error-continue>
    </error-handler>
</flow>

方案二:先浏览队列再消费,从根源避免超时错误

通过JMS:Browse组件先检查队列是否存在消息,仅当有消息时执行消费操作,彻底规避超时错误的产生:

  1. 在Scheduler之后添加JMS:Browse组件获取队列消息列表
  2. 通过Choice组件判断消息列表是否为空,有消息则执行消费和后续逻辑,无消息则打印提示并终止流程

修改后的完整配置:

<flow name="docusign-message-reprocessing-reports-subflow" doc:id="f3ffe923-ee3e-4e0d-8a29-ec874b9755d7" >
    <scheduler doc:name="Scheduler" doc:id="ff715c36-be3e-4f79-bdc9-db7934c75985" >
        <scheduling-strategy >
            <fixed-frequency timeUnit="HOURS" frequency="3" startDelay="1"/>
        </scheduling-strategy>
    </scheduler>
    <logger level="INFO" doc:name="Logger" doc:id="66ef28f0-c4a6-4bec-b824-a51ce7e8ea79" message="@@@@ ---&gt; scheduler triggered"/>
    
    <!-- 浏览队列获取消息列表 -->
    <jms:browse doc:name="Browse Queue" doc:id="browse-queue" config-ref="AMQ-DocuSign-Connector" destination="#[Mule::p('amq.docusign.reports.bqueue')]">
        <jms:consumer-type>
            <jms:queue-consumer />
        </jms:consumer-type>
    </jms:browse>
    
    <choice doc:name="Check for Messages" doc:id="check-messages">
        <when expression="#[!isEmpty(payload)]">
            <!-- 有消息时执行消费 -->
            <jms:consume doc:name="Consume" doc:id="e63155ec-7563-4409-bd83-c66e6e1c792a" config-ref="AMQ-DocuSign-Connector" destination="#[Mule::p('amq.docusign.reports.bqueue')]">
                <jms:consumer-type>
                    <jms:queue-consumer />
                </jms:consumer-type>
            </jms:consume>
            <logger level="INFO" doc:name="Logger" doc:id="47cd3399-a84d-476e-b065-b58c6d94079d" message="printing payload #[payload]"/>
            <logger level="INFO" doc:name="Logger" doc:id="b8c49215-383f-45e3-aaf3-2b9511a53828" message="#[&quot;Moving messages from DLQ&quot; ++ Mule::p('amq.docusign.reports.bqueue')  as String ++   &quot;to&quot; ++ Mule::p('amq.docusign.reports.topic') as String]" />
            <jms:publish doc:name="Publish" doc:id="44425d09-4ced-4a9d-a1c8-9c6259a2b6c9" destination="${amq.docusign.reports.topic}" config-ref="AMQ-DocuSign-Connector" destinationType="TOPIC" />
        </when>
        <otherwise>
            <!-- 无消息时打印提示并终止流程 -->
            <logger level="INFO" doc:name="Logger" doc:id="eb5f2d82-f0a3-4a8d-93f0-25ac4784e0fc" message="#[&quot;No message found in DLQ&quot; ++  Mule::p('amq.docusign.reports.bqueue')  as String ++  &quot;!&quot;]" />
            <stop doc:name="Stop" doc:id="stop-flow"/>
        </otherwise>
    </choice>
    
    <!-- 处理其他异常(如连接错误) -->
    <error-handler >
        <on-error-continue enableNotifications="true" logException="true" doc:name="On Error Continue" doc:id="general-error-handler" >
            <logger level="ERROR" doc:name="Logger" doc:id="error-log" message="Unexpected error: #[error.message]"/>
        </on-error-continue>
    </error-handler>
</flow>

方案对比

  • 方案一:改动较小,保留原有的等待超时逻辑,仅通过错误处理屏蔽日志并终止流程
  • 方案二:从根源避免超时错误,流程逻辑更清晰,无需处理超时异常,但需要额外的浏览操作

内容的提问来源于stack exchange,提问作者kushma gonna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 07:37:08