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

使用APIM入站send-request策略时无法实现内部响应缓存

问题分析与解决方案

首先明确:可以缓存send-request返回的响应,但你的策略存在两个核心问题导致缓存失效:

  1. return-response跳过了outbound阶段:你在inbound里用return-response直接返回结果,会跳过后续的backend和outbound阶段,导致outbound中的cache-store永远不会执行,缓存根本没机会被写入。
  2. 缓存查询时机与逻辑不匹配:cache-lookup放在最前面时缓存无对应数据,必然返回miss,且后续没有正确的缓存写入逻辑支撑。

修正后的策略代码(推荐方案)

调整策略流程,确保缓存写入逻辑能正常执行,同时保证缓存命中逻辑有效:

<policies>
    <inbound>
        <base />
        <!-- 优先从缓存查询,命中则直接返回 -->
        <cache-lookup vary-by-developer="false" vary-by-developer-groups="false" downstream-caching-type="none">
            <vary-by-header>Accept</vary-by-header>
            <vary-by-header>Accept-Charset</vary-by-header>
        </cache-lookup>
        <!-- 缓存未命中时,执行表存储查询 -->
        <set-variable name="SASToken" value="@("my sas key")" />
        <set-variable name="TableURL" value="@{string sastoken = context.Variables.GetValueOrDefault<string>("SASToken");return String.Format("https://storageaccount.table.core.windows.net/table()?{0}", sastoken);}" />
        <send-request mode="new" response-variable-name="data" timeout="20" ignore-error="false">
            <set-url>@($"{context.Variables.GetValueOrDefault("TableURL")}")</set-url>
            <set-method>GET</set-method>
            <set-header name="Content-Type" exists-action="override">
                <value>application/json</value>
            </set-header>
            <set-header name="Accept" exists-action="override">
                <value>application/json;odata=nometadata</value>
            </set-header>
        </send-request>
        <!-- 构造响应到context.Response,不直接终止流程 -->
        <set-status code="200" reason="Ok" />
        <set-header name="Content-Type" exists-action="override">
            <value>application/json</value>
        </set-header>
        <set-header name="Accept" exists-action="override">
            <value>application/json;odata=nometadata</value>
        </set-header>
        <set-body template="liquid">
                {
                  "result" : [
                       {{body}}  
                  ]
                }
        </set-body>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
        <!-- 响应构造完成后,存入缓存 -->
        <cache-store duration="1000" cache-response="true" />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

关键调整说明

  • 移除return-response:改用set-status、set-header、set-body直接修改context.Response,让流程能走到outbound阶段,确保cache-store执行。
  • 缓存逻辑顺序:先执行cache-lookup,APIM会自动在命中时返回缓存响应;未命中则执行数据查询与响应构造,最后在outbound完成缓存写入。
  • 缓存键一致性:cache-lookup的vary-by-header配置与请求头匹配,确保后续请求能正确匹配缓存键。

备选方案(保留return-response)

如果必须使用return-response,可在构造响应后手动调用cache-store,指定要缓存的响应变量:

<policies>
    <inbound>
        <base />
        <cache-lookup vary-by-developer="false" vary-by-developer-groups="false" downstream-caching-type="none">
            <vary-by-header>Accept</vary-by-header>
            <vary-by-header>Accept-Charset</vary-by-header>
        </cache-lookup>
        <set-variable name="SASToken" value="@("my sas key")" />
        <set-variable name="TableURL" value="@{string sastoken = context.Variables.GetValueOrDefault<string>("SASToken");return String.Format("https://storageaccount.table.core.windows.net/table()?{0}", sastoken);}" />
        <send-request mode="new" response-variable-name="data" timeout="20" ignore-error="false">
            <set-url>@($"{context.Variables.GetValueOrDefault("TableURL")}")</set-url>
            <set-method>GET</set-method>
            <set-header name="Content-Type" exists-action="override">
                <value>application/json</value>
            </set-header>
            <set-header name="Accept" exists-action="override">
                <value>application/json;odata=nometadata</value>
            </set-header>
        </send-request>
        <!-- 构造最终响应并存入变量 -->
        <set-variable name="finalResponse" value="@{
            var data = context.Variables.GetValueOrDefault<Response>("data");
            var body = data.Body.As<string>();
            return new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.OK,
                Content = new StringContent($"{{\"result\": [{body}]}}", Encoding.UTF8, "application/json")
            };
        }" />
        <!-- 手动存入缓存 -->
        <cache-store duration="1000" cache-response="true" response-variable-name="finalResponse" />
        <!-- 返回响应 -->
        <return-response response-variable-name="finalResponse" />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 21:14:58