Mule 4中使用on-error-continue避免JMS空队列错误日志
解决方案
方案一:修改错误处理器,捕获JMS超时错误并静默终止流程
问题根源是JMS Consume组件在队列无消息超时后会抛出JMS:TIMEOUT错误,当前错误处理器设置了logException="true",导致错误日志被打印。只需针对该错误类型调整错误处理逻辑:
- 修改错误处理器,指定仅捕获
JMS:TIMEOUT错误,关闭错误日志打印,同时终止流程避免后续组件执行 - 移除无效的
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="@@@@ ---> 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="#["Moving messages from DLQ" ++ Mule::p('amq.docusign.reports.bqueue') as String ++ "to" ++ 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组件先检查队列是否存在消息,仅当有消息时执行消费操作,彻底规避超时错误的产生:
- 在Scheduler之后添加
JMS:Browse组件获取队列消息列表 - 通过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="@@@@ ---> 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="#["Moving messages from DLQ" ++ Mule::p('amq.docusign.reports.bqueue') as String ++ "to" ++ 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="#["No message found in DLQ" ++ Mule::p('amq.docusign.reports.bqueue') as String ++ "!"]" /> <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
相关产品推荐
相关产品推荐

