【问题标题】:Azure API management configuring external caching policyAzure API 管理配置外部缓存策略
【发布时间】:2021-05-05 05:43:30
【问题描述】:

我们正在使用 Azure API 管理来发布、监控和维护 API。我们还为身份验证和授权实现了 B2C 登录。

我正在尝试为 API 配置外部缓存。不知何故,缓存策略不起作用。我参考以下链接https://docs.microsoft.com/en-us/azure/api-management/api-management-sample-cache-by-key

基于登录的用户租户 ID,我们希望将模板存储在缓存中,并稍后检索以供下一个请求。 这是我写的政策。

<policies>
    <inbound>
        <set-variable name="tenantId" value="@(context.Request.Headers.GetValueOrDefault("Authorization","").Split(' ')[1].AsJwt()?.Subject)" />
        <cache-lookup-value key="@("templates-" + context.Variables["tenantId"])" variable-name="templates" />
        <choose>
            <when condition="@(!context.Variables.ContainsKey("tenantId"))">
                <send-request mode="new" response-variable-name="templateResponse" timeout="15" ignore-error="true">
                    <set-url>https://abc.azure-api.net/api/notification/templates/?api-version=v1</set-url>
                    <set-method>GET</set-method>
                </send-request>
                <set-variable name="templates" value="@(((IResponse)context.Variables["templateResponse"]).Body.As<string>())" />
                <cache-store-value key="@("templates-" + context.Variables["tenantId"])" value="@((string)context.Variables["templates"])" duration="10000" />
            </when>
        </choose>
        <base />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

【问题讨论】:

    标签: azure azure-api-management api-management


    【解决方案1】:

    只要请求中有授权标头,APIM 就不会缓存请求,除非您启用私有响应缓存。

    您可以将 allow-private-response-caching 属性设置为 ture 以启用私有响应缓存 https://docs.microsoft.com/en-us/azure/api-management/api-management-caching-policies#elements

    如果它不能继续工作,那么我建议向 MS 团队提交支持票。

    【讨论】:

      【解决方案2】:

      我在编写策略时犯了一些错误。这是更正后的政策。

      <policies>
      <inbound>
          <set-variable name="userId" value="@(context.Request.Headers.GetValueOrDefault("Authorization","").Split(' ')[1].AsJwt()?.Subject)" />
          <cache-lookup-value key="@("templates-" + context.Variables["userId"])" variable-name="templates" caching-type="external" />
          <choose>
              <when condition="@(!context.Variables.ContainsKey("templates"))">
                  <send-request mode="new" response-variable-name="templateResponse" timeout="15" ignore-error="true">
                      <set-url>https://appname.azurewebsites.net/api/templates</set-url>
                      <set-method>GET</set-method>
                      <set-header name="Authorization" exists-action="override">
                          <value>@(context.Request.Headers.GetValueOrDefault("Authorization",""))</value>
                      </set-header>
                  </send-request>
                  <set-variable name="templates" value="@(((IResponse)context.Variables["templateResponse"]).Body.As<string>())" />
                  <cache-store-value key="@("templates-" + context.Variables["userId"])" value="@((string)context.Variables["templates"])" duration="10000" />
              </when>
          </choose>
          <base />
      </inbound>
      <backend>
          <base />
      </backend>
      <outbound>
          <set-body>@((string)context.Variables["templates"])</set-body>
          <base />
      </outbound>
      <on-error>
          <base />
      </on-error>
      

      【讨论】: