设置sequential="true"后Iterate mediator仍非顺序执行问题排查
问题描述
输入数据:
<uList> <user> <id>12</id> </user> <user> <id>13</id> </user> <user> <id>14</id> </user> <user> <id>15</id> </user> </uList>
需要遍历该列表并顺序执行SCIM GET API调用,但使用以下Iterate中介配置后,请求仍在并行执行:
<iterate expression="//*[local-name()='user']" sequential="true"> <target> <sequence> <property name="uri.var.uuid" expression="//*[local-name()='scimId']" scope="default" type="STRING"/> <log level="custom"> <property name="uri.var.uuid" expression="//*[local-name()='scimId']"/> </log> <property name="NO_ENTITY_BODY" value="true" scope="axis2" type="BOOLEAN"/> <header name="Content-Type" scope="transport" action="remove"/> <call> <endpoint> <http method="GET" uri-template="https://run.mocky.io/v3/ebc2eef8-6012-4fbb-b0b5-d063b68c6400"/> </endpoint> </call> <property name="userName" expression="json-eval($.userName)" scope="default" type="STRING"/> <payloadFactory media-type="json"> <format>{"responses":{"username":"$1", "scimId":"$2"}}</format> <args> <arg evaluator="xml" expression="$ctx:userName"/> <arg evaluator="xml" expression="$ctx:uri.var.uuid"/> </args> </payloadFactory> <script language="js">java.lang.Thread.sleep(5000);</script> </sequence> </target> </iterate>
问题分析与解决
- 核心并行原因:Call中介默认异步
Iterate的sequential="true"仅控制迭代消息的生成顺序,但Call中介默认采用非阻塞异步调用模式,会直接发送请求而不等待响应,导致多个API调用并行执行。
解决方法:给Call中介添加blocking="true"属性,强制同步阻塞执行,确保上一个API调用完成后再执行下一次迭代:
<call blocking="true"> <endpoint> <http method="GET" uri-template="https://run.mocky.io/v3/ebc2eef8-6012-4fbb-b0b5-d063b68c6400"/> </endpoint> </call>
- 额外的路径错误问题
输入数据中user节点下的字段是<id>,但配置里用//*[local-name()='scimId']取值,会导致uri.var.uuid为空,需修正为:
<property name="uri.var.uuid" expression="//*[local-name()='id']" scope="default" type="STRING"/> <log level="custom"> <property name="uri.var.uuid" expression="//*[local-name()='id']"/> </log>
- 可选:结果聚合
如果需要将所有迭代的响应结果聚合,需在Iterate之后添加Aggregate中介,否则最终只会保留最后一次迭代的响应内容。
内容的提问来源于stack exchange,提问作者prime
相关产品推荐
相关产品推荐

