如何在WSO2 Integration Studio中依次调用多个Endpoint?遇超时问题
问题分析与解决方案
问题原因
你遇到的Socket超时问题,核心是Iterate Mediator的异步执行特性与提前发送响应的冲突:
- 默认情况下Iterate会异步处理每个分支,而你在Iterate之后直接调用
<respond/>,会立刻给客户端返回响应并关闭连接,但此时Iterate内部的Call请求还在后台执行,导致EI与客户端的连接提前终止,触发超时警告。 - 另外前三个Call Mediator会依次覆盖消息上下文的Payload,若第三个Call返回的
<accounts/account>结构不符合预期,也可能导致Iterate无法正确触发,但从日志看主要矛盾还是异步执行与提前响应的冲突。
修复方案
1. 添加Aggregate Mediator等待Iterate完成
修改InSequence,确保所有Iterate分支执行完毕后再发送响应:
<api context="/NumSequence" name="NumSequence" xmlns="http://ws.apache.org/ns/synapse"> <resource methods="GET"> <inSequence> <call> <endpoint> <http method="get" uri-template="http://ebs-dev:8290/services/RADMINDataService/numseqdrop"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>-1</progressionFactor> <maximumDuration>0</maximumDuration> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </http> </endpoint> </call> <call> <endpoint> <http method="get" uri-template="http://ebs-dev:8290/services/RADMINDataService/numseqcreate"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>-1</progressionFactor> <maximumDuration>0</maximumDuration> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </http> </endpoint> </call> <call> <endpoint> <http method="get" uri-template="http://ebs-dev:8290/services/CRMDataService/ReadUsername"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>-1</progressionFactor> <maximumDuration>0</maximumDuration> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </http> </endpoint> </call> <iterate expression="//accounts/account" id="numseq-iterate" aggregateOnComplete="true"> <target> <sequence> <payloadFactory media-type="json" template-type="freemarker"> <format><![CDATA[{ "_postaddusername": { "NumSequence":${payload.account.NumSequence}, "Prefixe":"${payload.account.Prefixe}" } }]]></format> <args/> </payloadFactory> <call> <endpoint> <http method="post" uri-template="http://ebs-dev:8290/services/RADMINDataService/AddUsername"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>-1</progressionFactor> <maximumDuration>0</maximumDuration> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </http> </endpoint> </call> </sequence> </target> </iterate> <aggregate id="numseq-iterate"> <completeCondition> <messageCount min="-1" max="-1"/> </completeCondition> <onComplete> <respond/> </onComplete> </aggregate> </inSequence> <outSequence/> <faultSequence/> </resource> </api>
2. 关键修改说明
- 给
<iterate>添加id="numseq-iterate"和aggregateOnComplete="true",标记需要聚合的迭代任务。 - 添加
<aggregate>节点,通过id关联对应的Iterate,设置<completeCondition>等待所有分支执行完成,在<onComplete>里调用<respond/>,确保所有后台请求执行完毕后再给客户端返回响应。 - 若需要保留Iterate分支的响应结果,可以在
<onComplete>里添加逻辑处理聚合后的消息。
3. 额外优化建议
- 为每个Call Mediator添加
<property name="DISABLE_CHUNKING" value="true" scope="axis2"/>,避免分块传输导致的潜在超时问题。 - 检查第三个Call返回的XML结构是否严格匹配
//accounts/account表达式,确保Iterate能正确遍历目标节点。
内容的提问来源于stack exchange,提问作者Oussama Nairi
相关产品推荐
相关产品推荐

