后端机器返回错误的gzip数据导致varnish出现503错误

近期,笔者维护的varnish服务器,不定期出现503错误,按照以往经验,调整超时时间、请求和响应header 正文缓冲区大小,均无解。

然后,只有从varnish本身的行为入手,在varnish机器上启动varnishlog 观察日志,发现有一处异常

ObjHeader      Content-Length: 164

Fetch_Body     3 length stream

Gzip           Gunzip error: -3 (incorrect header check)

FetchError     Invalid Gzip data: incorrect header check

Gzip           u F - 2 0 0 0 0

从字面上看,是gzip数据格式导致的,然后就反复猜想,有可能是源服务器返回了错误的gzip数据,使用curl访问源服务器:

curl -i -H "Accept-Encoding:gzip" -H "Host:域名"  http://源服务器ip/文件路径

输出结果:

222912_lJvv_1168437.png

根据源服务器的响应header Content-Encoding:gzip 明确告诉我们,正文部分已经使用gzip压缩,但是观察输出,却很诡异,输出的却是明文的未压缩过的内容,但最后一行,全是空字符,最后一个字符,倒是很像是gzip压缩过的内容,说明服务器欺骗了我们,虽然告诉我们内容是gzip压缩过的,但实际上却是不正确的gzip结果。


然后,我们再尝试获取不压缩的内容:

curl -i  -H "Host:域名"  http://源服务器ip/文件路径

223405_IZBZ_1168437.png

这次服务器返回了没有压缩过的内容,明显是正确的了。

分析结果:

  1. 默认情况下,无论客户端是否支持gzip, varnish在请求源服务器时,会自动增加Accept-Encoding:gzip指令,期待获取压缩内容

  2. varnish取到结果后,会根据vcl_backend_response事件中的beresp.do_gzip = true/false指令,决定是否把内容gzip压缩后缓存起来(显然压缩后缓存,会节省大量内存或磁盘资源),如果这个指令没有设置,则使用原因内容缓存,不作压缩任何压缩处理。

  3. 无论源服务器是否支持gzip压缩,无论缓存内容是否已经gzip压缩,只要客户端支持gzip压缩,varnish会返回gzip的内容。另一面,如果客户端不支持gzip压缩,varnish会将缓存的gzip压缩过的内容进行解压,再发送给客户端。

  4. varnish是设计就是以最佳性能为考虑的,所以默认是启用gzip压缩的。

知道这几个原理后,如果源机器返回了非法的gzip内容,我们可以用以下任何一个方法处理:

  1.  让源机器返回正确的gzip内容,或禁止源机器gzip压缩。

  2. 让varnish在请求源机器时,期望获取不压缩内容

  3. 彻底禁止掉varnish的所有gzip压缩功能(向客户端发送不压缩的内容——无论客户端是否支持gzip;  请求源服务器时,期望获取不压缩内容)

以上三个方法,任选 一个,即可解决这个问题:

第2条的配置文件方法(在vcl文件中设置):

sub vcl_backend_fetch {

        unset bereq.http.Accept-Encoding;

        return (fetch);

}

第3条解决方法:

varnishd启动时,使用-p http_gzip_support=off 完全关闭掉gzip支持,如果是使用yum安装,可在/et/sysconfig/varnish文件中指定

如果varnish已经启动,不允许重启,则可在运行时修改它, 使用 varnishadm 命令,进入命令行界面,查看参数:

param.show

可直接输入help, 查看扩展的指令, 使用以下命令全局关闭gzip支持:

param.set http_gzip_support off

经过这样处理后,偶尔返回503错误的问题得到了解决。

转载于:https://my.oschina.net/zxu/blog/603456

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值