Google CDN 随机不提供 gzip 内容

Google CDN random not serving gzip content

我需要一些高级人员给我建议这是 Google CDN 错误还是我遗漏了什么。我在 4 个月前发现了这个错误,试图联系他们的支持,但他们太粗鲁了,我什至不想在这里谈论这个。他们接受了,至少他们告诉我他们会将问题发送给 back-end 团队,但在那之后他们删除了问题跟踪器并且他们不再回复我的电子邮件。这就是我在这里问的主要原因。

问题

Google CDN 随机不向最终用户提供 gzip 内容。因此,他们下载 500KB 文件而不是 ~70KB。我不能直接向我的来源产生这个问题,但我可以在 Google CDN 上很容易地产生这个问题。

这是对 CDN 的示例请求:

要求:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US,en;q=0.8,bg;q=0.6,hr;q=0.4,mk;q=0.2,sr;q=0.2
Cache-Control:no-cache
Connection:keep-alive
Cookie: example
Host: example.com
Pragma:no-cache
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36

回复:

Accept-Ranges:bytes
Age:58422
Alt-Svc:clear
Cache-Control:public, max-age=604800
Content-Length:550158
Content-Type:text/css
Date:Tue, 04 Apr 2017 03:45:53 GMT
Expires:Tue, 11 Apr 2017 03:45:53 GMT
Last-Modified:Sun, 19 Mar 2017 01:50:22 GMT
Server:LiteSpeed
Via:1.1 google

如您所见,我的请求有 accept-encoding:gzip header 但我收到的不是 gzip 内容。我收到的不是 70KB,而是 500KB。另请注意年龄 header,该项目在 CDN 上 cached/exist 58422 秒!

这是来自另一台机器(美国)的相同请求

要求:

:authority: xxx
:method:GET
:path:/wp-content/themes/365/style.css
:scheme:https
accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
accept-encoding:gzip, deflate, sdch, br
accept-language:en-US,en;q=0.8
cache-control:no-cache
cookie: xxx
pragma:no-cache
upgrade-insecure-requests:1
user-agent:Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36

回复:

accept-ranges:bytes
age:58106
alt-svc:clear
cache-control:public, max-age=604800
content-encoding:gzip
content-length:72146
content-type:text/css
date:Tue, 04 Apr 2017 03:49:28 GMT
expires:Tue, 11 Apr 2017 03:49:28 GMT
last-modified:Sun, 19 Mar 2017 01:50:22 GMT
server:LiteSpeed
status:200
vary:Accept-Encoding
via:1.1 google

如您所见,我从其他服务器获得了 gzip 内容。

我有大量的 HAR 文件和视频来证明这个错误,但让我们保持简单。 Google GCP 仪表板中提供了 CDN 日志,请查看它们的外观。

如果我所有的访问者都不支持 gzip,那 GoogleBot 呢?

我还分析了我的服务器日志,我发现该文件的 99% 响应大小的统计数据是 gzip,只有少数请求不是 gzip。非常合乎逻辑,因为一些访客或我更喜欢说机器人请求的文件没有 gzip header.

暂时解决问题

如果我清除 CDN 缓存,这个问题在下一个 minutes/hours 中就不存在了。一段时间后,它仍然会发生。此外,此问题并不总是发生,而是随机发生。我得到了解析 CDN 日志并向我显示图表的系统,这实际上是我发现此错误的方式。

每当我看到图表带宽增加(正常情况下增加一倍)时,当我登录 google 仪表板并检查日志时,我发现那些 500KB 的日志占该文件请求的 50%,而且很容易在浏览器中产生错误,我只是登录到我的服务器,请求文件并获得随机结果。

如果问题出在我的问题上,我会很高兴,因为我会在 1 分钟内解决,但我认为这是 Google CDN 错误。如果有人更喜欢 CDN 技术来帮助我或来自 Google Cloud 的人,我会很高兴。

编辑:

正如我所说,这个错误发生在随机时间范围内,这是我现在录制的一段视频,向我们展示了 'NO BUG TIME FRAME'。如您所见,每个响应都被压缩了。

NO BUG TIME FRAME CDN VIDEO

编辑 2:

这是一个图表,显示了单个 .css url 测试的 gzip 和非 gzip 响应的数量。

编辑 3:

在第一个图形图像上,线条是 stack-able,这是没有堆叠的相同图形。如您所见,有些时间几乎 100% 不是 gzip 响应。

编辑4:

这是同一个 css 文件的原始解析日志。

1060 个请求的响应大小低于 100KB。 200,304,206 响应代码。 32 个请求的响应大小超过 100KB。 200 和 206 响应代码。

编辑5:

分析 4 月 1 日至 7 日的日志,这里有一些额外的统计数据。css url:

19803 个 CDN 请求使用 > 100KB(不是 gzip)

41004 个 CDN 请求被处理 < 100KB (gzip)

29 从源缓存填充 > 100KB(不是 gzip)

924 来自源的缓存填充 < 100KB (gzip)

423 Cache-To-Cache 填充 > 100KB(不是 gzip)

2295 Cache-To-Cache 填充 < 100KB (gzip)

我很惊讶 Cache-To-Cache 填充非常有效,太棒了。

解决方案

即使在 Google CDN 中也没有原始错误。问题是当 Google CDN 收到一个 cache-able 没有 'Vary:Accept-Encoding' 的实体时,当请求没有发送 'Accept-Encoding:gzip' 时,所以 Google CDN 将存储未压缩的响应并将 覆盖所有存储的压缩缓存实体。因此,下次当用户尝试获取某些文件时,例如 .css,Google CDN 将回答如下:

  1. 我从源头收到了这个文件,它没有任何变化。
  2. 发送未压缩的响应。

请注意,网络服务器未配置为在没有 'Accept-Encoding:gzip' header 的请求上发送 'Vary:Accept-Encoding' header。我在 Litespeed、Apache、Nginx 和 Cloudflare Nginx 上对此进行了测试。

我强烈建议Google团队更新有关此的文档。有一个关于 'Vary headers' 的声明,但没有人会明白这个问题的要点因为不是我,不是 Google 一级支持(我还与两名 Google 支持人员就 Google 问题跟踪器进行了 20 天的沟通),stack-overflow 或其他人回答了问题.

另外文档说:

In addition to the request URI, Cloud CDN respects any Vary headers that instances include in responses.

但是当请求没有 'Vary' header.

时什么也没有

我是这样解决的:

<FilesMatch '.(js|css|xml|gz|html|txt|xml|xsd|xsl|svg|svgz)$'>
    Header merge Vary Accept-Encoding
  </FilesMatch>

Google Cloud CDN 既不压缩也不解压缩来自您的来源的响应。相反,它尊重源服务器的 Vary:Accept-Encoding 响应 header 并根据客户端的 Accept-Encoding 请求 header 缓存单独的变体。支持 gzip 压缩的客户端应该得到一种变体,而不支持 gzip 压缩的客户端应该得到另一种。

问题是您提供的示例未压缩响应缺少 Vary:Accept-Encoding header:

Accept-Ranges:bytes
Age:58422
Alt-Svc:clear
Cache-Control:public, max-age=604800
Content-Length:550158
Content-Type:text/css
Date:Tue, 04 Apr 2017 03:45:53 GMT
Expires:Tue, 11 Apr 2017 03:45:53 GMT
Last-Modified:Sun, 19 Mar 2017 01:50:22 GMT
Server:LiteSpeed
Via:1.1 google

以上响应指示 Cloud CDN 对所有客户端使用未压缩的变体,无论它们是否支持 gzip 压缩。一旦没有 Vary: Accept-Encoding header 的响应在缓存中结束,Cloud CDN 将为所有客户端使用该缓存的响应。修复是为了让源服务器在其响应中包含 Vary: Accept-Encoding header。

您能否分享有关如何启用 gzip 压缩的详细信息?看起来有时您的源服务器无法在其响应中包含 Vary: Accept-Encoding header 。当它认为客户端不支持 gzip 压缩时,也许它不包括 header?