【问题标题】:Azure API Management Cache IssueAzure API 管理缓存问题
【发布时间】:2020-04-13 15:37:05
【问题描述】:

目标:使用 API 管理缓存策略来缓存一个永远不会改变的 json 响应。

原始(无缓存)
此策略由一个 azure 函数支持,该函数返回一个永不更改的 json 响应。

<policies>
    <inbound>
        <base />
        <set-backend-service id="apim-generated-policy" backend-id="azfunc-fluffyoauth2" />
        <rewrite-uri template="/WellKnownOpenidConfiguration" />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

考虑到这可能是缓存的好东西,我介绍了缓存查找策略。

<policies>
    <inbound>
        <base />
        <set-backend-service id="apim-generated-policy" backend-id="azfunc-fluffyoauth2" />
        <rewrite-uri template="/WellKnownOpenidConfiguration" />
        <cache-lookup vary-by-developer="false" vary-by-developer-groups="false" downstream-caching-type="none" />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
        <cache-store duration="36000" />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

我看到的是缓存版本返回一个我认为是 gzip 压缩的二进制文件。这会导致预期它是原始 json 的下游代码中断。这个响应是一个 openid 连接发现文档,具有讽刺意味的是,如果我将 API Management 的 jwt-policy 指向它,它也会中断。

var auth0Domain = "https://apim-mycompany.azure-api.net/oauth2";
string responseString = null;
try
{
    var url = $"{auth0Domain}/.well-known/openid-configuration-cached";
    Console.WriteLine($"-------------------");
    Console.WriteLine($"{url}");
    var httpClient = new HttpClient();
    var response = await httpClient.GetAsync(new Uri($"{auth0Domain}/.well-known/openid-configuration-cached"));
    responseString = await response.Content.ReadAsStringAsync();
    Console.WriteLine($"-------------------");
    Console.WriteLine($"{responseString}");
    Console.WriteLine($"-------------------");
    JsonConvert.DeserializeObject<OpenIdConnectConfiguration>(responseString);
}
catch (Exception ex)
{
    Console.WriteLine($"Error:{ex.Message}");
    Console.WriteLine($"-------------------");
    return;
}



curl -I --location --request GET 'https://apim-fluffyoauth2.azure-api.net/oauth2/.well-known/openid-configuration-cached'
HTTP/1.1 200 OK
Cache-Control: no-store, must-revalidate, no-cache
Pragma: no-cache
Content-Length: 558
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
Expires: Tue, 14 Apr 2020 18:50:53 GMT
Vary: Accept-Encoding
Request-Context: appId=cid-v1:dfeba42c-e636-42bc-b501-7c77563c3e7b,appId=cid-v1:dfeba42c-e636-42bc-b501-7c77563c3e7b
Date: Tue, 14 Apr 2020 18:50:53 GMT

问题:

缓存策略在做什么?
如何将其更改为仍缓存但响应非缓存版本的功能?

【问题讨论】:

  • 响应本身被 gzip 压缩不应该是一个问题,只要所有内容标题都到位。您能否添加一个包含从 APIM 获得的所有标头的示例缓存响应?
  • APIM 会突然不做 gzip,我所要做的就是修改缓存策略 TTL 并保存。这会触发它开始发送 gzip。 apim-fluffyoauth2.azure-api.net/oauth2/.well-known/… HTTP/1.1 200 OK Cache-Control: no-store, must-revalidate, no-cache Pragma: no-cache Content-Length: 558 Content-Type: application/json; charset=utf-8 内容编码:gzip 过期:格林威治标准时间 2020 年 4 月 14 日星期二 18:50:53 变化:接受编码日期:格林威治标准时间 2020 年 4 月 14 日星期二 18:50:53
  • APIM 总是将所有客户端标头发送到后端,您是否发送了接受编码?您可能希望在缓存查找策略中添加 vary="accept-encoding",如果客户端没有要求,这将阻止 APIM 回复缓存的 gzip 内容。
  • 我添加了 Accept 和 Accept-Charset。这似乎已经解决了。你得到你想要的。 接受接受字符集

标签: azure-api-management


【解决方案1】:

添加以下内容;

<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>

产生最终策略。

<policies>
<inbound>
    <base />
    <set-backend-service id="apim-generated-policy" backend-id="azfunc-fluffyoauth2" />
    <rewrite-uri template="/WellKnownOpenidConfiguration" />
    <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>
</inbound>
<backend>
    <base />
</backend>
<outbound>
    <base />
    <cache-store duration="3600" />
</outbound>
<on-error>
    <base />
</on-error>

现在导致 API 管理在不要求时不执行 gzip 编码。

我还在想为什么 API Management 会突然停止对原始问题进行 gzip 编码。有时它做到了,然后停止,这导致对正在发生的事情感到困惑。

【讨论】:

  • APIM 不“做”gzip 编码。客户端请求,除非通过策略进行修改,否则将完整地发送到后端。因此,如果客户端不发送 Accept-Encoding: gzip,APIM 也不会将该标头发送到后端,并且后端也不会响应 gzip 压缩的内容。
  • Vitaliy,您介意与我联系吗,因为这不是我在现场看到的情况。我可以通过屏幕分享我正在做的事情并向您展示 apim 如何响应。
  • 我不是版主,所以不能给你发私信。而且我在您的个人资料中找不到任何联系信息。您可以添加您发送到 APIM 的请求以及您从中获得的响应,以便我查看。
猜你喜欢
  • 2020-06-11
  • 2017-03-18
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 2015-12-08
相关资源
最近更新 更多