http 请求的 gzip 不正确,无法找到执行此操作的人

http 请求的 gzip 不正确,无法找到执行此操作的人

我们发现 HTTP 响应出现了一些非常奇怪的混乱,我们不知道是什么原因造成的。我们有一个应用服务器处理 JSON 请求。有时,响应会以 gzip 压缩的形式返回,但标头不正确,导致浏览器无法正确解释。

这个问题是间歇性的,并且会随着时间的推移而改变。昨天早上,它似乎有 50% 的时间会失败,事实上,似乎与我们的两个负载平衡服务器之一有关。下午晚些时候,它每 1000 次失败只有 20 次,并且与应用服务器无关。

两台应用服务器运行的是带有 mod_wsgi 和 Django 应用堆栈的 Apache 2.2。它们具有相同的 Apache 配置和源代码树,甚至在 Red Hat 上安装的软件包也相同。前面有一个硬件负载平衡器,我不知道品牌或型号。

Akamai 也是食物链的一部分,尽管我们删除了 Akamai,但问题仍然存在。

以下是一个很好的请求和响应:

* Connected to example.com (97.7.79.129) port 80 (#0)
> POST /claim/ HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
> Host: example.com
> Accept: */*
> Referer: http://example.com/apps/
> Accept-Encoding: gzip,deflate
> Content-Length: 29
> Content-Type: application/x-www-form-urlencoded
> 
} [data not shown]
< HTTP/1.1 200 OK
< Server: Apache/2
< Content-Language: en-us
< Content-Encoding: identity
< Content-Length: 47
< Content-Type: application/x-javascript
< Connection: keep-alive
< Vary: Accept-Encoding
< 
{ [data not shown]
* Connection #0 to host example.com left intact
* Closing connection #0
{"msg": "", "status": "OK", "printer_name": ""}

这是一个糟糕的例子:

* Connected to example.com (97.7.79.129) port 80 (#0)
> POST /claim/ HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
> Host: example.com
> Accept: */*
> Referer: http://example.com/apps/
> Accept-Encoding: gzip,deflate
> Content-Length: 29
> Content-Type: application/x-www-form-urlencoded
> 
} [data not shown]
< HTTP/1.1 200 OK
< Server: Apache/2
< Content-Language: en-us
< Content-Encoding: identity
< Content-Type: application/x-javascript
< Content-Encoding: gzip
< Content-Length: 59
< Connection: keep-alive
< Vary: Accept-Encoding
< X-N: S
< 
{ [data not shown]
* Connection #0 to host example.com left intact
* Closing connection #0
�V�-NW�RPR�QP*.I,)-���A���̼�Ԣ����T��Z�
��/

对于糟糕的回应,有两点需要注意:

  1. 它有两个 Content-Encoding 标头,而浏览器似乎使用第一个。因此,它们会看到一个身份编码标头和经过 gzip 压缩的内容,因此无法解释响应。

  2. 错误的响应有一个额外的“XN:S”标头。

也许如果我能找出哪个中介在响应中添加了“XN:S”标头,我就能找到罪魁祸首……

答案1

一些额外的线索

根据http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5

  • 身份默认(身份)编码;不使用任何转换。此内容编码仅在 Accept-Encoding 标头中使用,不应在 Content-Encoding 标头中使用。

Akamai 似乎忽略了服务器可以在其响应中包含此标头的事实,并且在将编码更改为“gzip”时不会将其删除。

由于上游服务器“不应该”首先添加标头,因此这是解决此问题的另一种方法。

答案2

您的建筑是什么样的?

请求路径中是否有反向代理?apache 中加载了哪些模块?apache 配置是什么样的?如果禁用 mod_deflate,是否仍会发生这种情况?是否有一个 php 脚本使用 ob_start 处理 json 输出并处理其自身的压缩?

答案3

我怀疑是负载均衡器缓存的问题。尝试在响应中添加反缓存标头,看看问题是否仍然存在。这可能会大大增加您的服务器负载。

相关内容