Azure APIM禁用函数应用时未触发重试策略问题咨询
核心问题
你的重试策略存在3处逻辑错误,导致跨区域故障转移完全不生效:
- 后端地址配置位置错误
<set-backend-service>放在<inbound>节点时,仅会在请求首次进入APIM时执行1次。后续<backend>节点内的重试循环不会重复触发inbound阶段逻辑,即使RetryCounter变量在重试时更新,后端地址始终是首次配置的悉尼节点,永远不会切到墨尔本备用节点。 - 重试块内执行顺序错误
当前逻辑在<retry>块内先累加计数器,再发送请求:首次进入重试块还未发任何请求时,计数器就从0被加到1,第一次请求发往悉尼返回403后,第二次重试时计数器已经为2,且后端地址未更新,请求依然会发往悉尼节点。 - 变量拼写错误
你配置的悉尼后端变量名写为{{syndey-function-app}},存在拼写错误(正确应为sydney),如果命名值实际拼写为sydney,会直接导致首次后端地址配置失效。
另外你当前的重试条件context.Response.StatusCode > 400本身可以覆盖403状态码,和你收到的停止站点403响应匹配,这部分逻辑没有问题。
修正后可用策略
将后端切换逻辑移到<retry>块内部,保证每次发请求前都根据当前计数器值选中对应后端,同时调整计数器累加时机,补充空响应判断避免异常:
<policies> <inbound> <base /> <!-- 初始化重试计数器,inbound阶段仅执行一次 --> <set-variable name="RetryCounter" value="0" /> </inbound> <backend> <retry count="1" interval="0" first-fast-retry="true" condition="@( context.Response != null && context.Response.StatusCode > 400 )"> <!-- 每次发送请求前,根据当前计数器值选中对应区域后端 --> <choose> <when condition="@(context.Variables.GetValueOrDefault<int>('RetryCounter', 0) == 0)"> <set-backend-service base-url="{{sydney-function-app}}" /> </when> <otherwise> <set-backend-service base-url="{{melbourne-function-app}}" /> </otherwise> </choose> <!-- 转发请求到选中的后端 --> <forward-request buffer-request-body="true" timeout="15"/> <!-- 请求完成后再累加计数器,为下一次重试做准备 --> <set-variable name="RetryCounter" value="@(context.Variables.GetValueOrDefault<int>('RetryCounter', 0) + 1)" /> </retry> </backend> <outbound> <base /> </outbound> <on-error> <base /> </on-error> </policies>
验证说明
- 修正后首次请求会发往悉尼主节点,返回403后立即触发重试,第二次请求自动切到墨尔本备用节点,可通过APIM内置的请求追踪功能查看两次后端调用的目标地址
- 两个区域的Function App独立运行正常的前提下,重试请求会正常打到墨尔本节点,对应Application Insights和Function日志都会留下记录
- 若需要覆盖更多故障场景(比如网络超时、连接重置),可以把对应异常条件补充到retry的condition判断里
内容的提问来源于stack exchange,提问作者Oscar Hermoso
相关产品推荐
相关产品推荐

