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

Azure API Management缓存配置:缓存响应并跨端点失效

问题描述

我有一个连接Azure Function的Azure API Management(通过Function App自动生成API),包含以下端点:

  • GET /GetEvents
  • POST /AddEvent
  • ...

事件添加操作不频繁但访问量高,需要实现:缓存GET /GetEvents的完整响应,调用POST /AddEvent时让该缓存失效。

之前使用cache-store和cache-lookup策略的配置如下:

<policies>
    <inbound>
        <base />
        <set-backend-service id="apim-generated-policy" backend-id="app-test" />
        <cache-lookup vary-by-developer="false" vary-by-developer-groups="false" allow-private-response-caching="true" must-revalidate="false" downstream-caching-type="public" />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
        <cache-store duration="@((new Random(context.RequestId.GetHashCode()).Next(40, 50)) * 3 * 60)" />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

但尝试用cache-remove-value删除缓存时,发现Redis中的缓存键是自动生成的(格式类似3_apimpbdhsanlkcmeaojfcewjfdsabucbeiuaw1qazerfvg.12345678_app-test;rev=1.11111111_get-getevents.12345678_4_https_apim.azure-api.net_443_/app-test/GetEvents),无法直接指定键值删除。

之后尝试用cache-store-value和cache-lookup-value自定义键值,但序列化响应失败,配置如下:

<policies>
    <inbound>
        <base />
        <set-backend-service id="apim-generated-policy" backend-id="app-test" />
        <cache-lookup-value key="GetEvents" variable-name="eventsList" />
    </inbound>
    <backend>
        <!--base: Begin Global scope-->
        <forward-request />
        <!--base: End Global scope-->
    </backend>
    <outbound>
        <base />
        <cache-store-value key="GetEvents" value="@(JsonConvert.SerializeObject(context.Response.Body.AsFormUrlEncodedContent()))" duration="@((new Random(context.RequestId.GetHashCode()).Next(40, 50)) * 3 * 60)" />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

现在有两个问题:

  1. 是否可以使用cache-store指定缓存条目键值,以便在其他端点通过cache-remove-value策略删除?
  2. 是否可以存储某个端点的完整响应(类似cache-lookup的效果),并通过另一个端点使该缓存失效?
解决方案

问题1:能否用cache-store指定缓存键值?

不行。cache-store和cache-lookup是APIM自动管理缓存键的策略,生成的键包含请求上下文信息(如API名称、路径、协议等)且带有随机前缀,无法手动指定固定键值,因此无法直接通过cache-remove-value匹配删除。

问题2:如何存储完整响应并跨端点失效缓存?

可以通过cache-lookup-value+cache-store-value配合条件策略实现,核心是正确读取和序列化响应内容,具体配置如下:

1. 为GET /GetEvents配置缓存逻辑

<policies>
    <inbound>
        <base />
        <set-backend-service id="apim-generated-policy" backend-id="app-test" />
        <!-- 先尝试从缓存读取数据 -->
        <cache-lookup-value key="GetEventsCache" variable-name="cachedEvents" />
        <!-- 如果缓存命中,直接返回缓存内容,跳过后端请求 -->
        <choose>
            <when condition="@(context.Variables.ContainsKey("cachedEvents"))">
                <set-body>@((string)context.Variables["cachedEvents"])</set-body>
                <set-status code="200" reason="OK" />
                <return-response />
            </when>
        </choose>
    </inbound>
    <backend>
        <forward-request />
    </backend>
    <outbound>
        <base />
        <!-- 将完整响应内容转为字符串存入缓存 -->
        <cache-store-value key="GetEventsCache" value="@(context.Response.Body.As<string>())" duration="@((new Random(context.RequestId.GetHashCode()).Next(40, 50)) * 3 * 60)" />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

2. 为POST /AddEvent配置缓存失效逻辑

<policies>
    <inbound>
        <base />
        <set-backend-service id="apim-generated-policy" backend-id="app-test" />
    </inbound>
    <backend>
        <forward-request />
    </backend>
    <outbound>
        <base />
        <!-- 删除指定的缓存键 -->
        <cache-remove-value key="GetEventsCache" />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

关键说明

  • 使用context.Response.Body.As<string>()可以正确读取响应的字符串内容,避免序列化错误;
  • 通过<choose>+<when>判断缓存是否命中,命中则直接返回缓存内容,无需调用后端;
  • POST /AddEvent处理完成后,用cache-remove-value删除固定键GetEventsCache,实现缓存失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 14:03:19