HTTP Gzip压缩问题总结

昨天线上进行机房迁移,因为请求量不大,打算先用nginx进行转发。结果今天业务反馈,返回的数据,解析出来内容为乱码。javascript

背景

上海机房因为网络不稳定,须要将机房迁移到无锡。上海机房使用F5进行转发和负载均衡,迁移到无锡机房因为资源限制,而且业务访问量不大,使用nginx进行转发和负载均衡。css

可是在无锡机房启动后,发现部分业务收到的部分数据是乱码。具备必定的随机性html

机房图

紧急处理方案

因为业务数据没法更新,紧急状况下切换上海机房,无锡机房暂时不启用。java

问题跟踪与定位

总体回顾

从整个访问流程来看,只有中间的F5换成了Nginx,访问方PORTAL未变(无配置变更、无升级更新),服务提供方WX_GDC直接从SH_GDC拷贝过来(惟一的变化是数据库配置)。nginx

初步分析

Nginx转发存在一些问题 WX_GDC数据库乱码。这个DBA很快确认没有乱码,焦点放到Nginx上。数据库

大胆推测

Nginx在转发时HTTP协议某些处理有问题浏览器

当心求证

请出网络神器--tcpdump,抓包对比正常和异常的数据包。缓存

2015-11-21 09:51:04.514918 IP 100.84.73.45.51377 > 100.84.73.34.9920: Flags [P.], seq 418240356:418240642, ack 340809695, win 1024, options [nop,nop,TS val 3214173339 ecr 3214153356], length 286
E..R.W@.@.KLdTI-dTI-..&....d.PW.....\G.....
..d.....POST /Application/pullConfig HTTP/1.1
Host: 100.84.73.34:9920
Accept-Encoding: gzip
Connection: keep-alive
Accept: */*
User-Agent: NING/1.0
Content-Length: 69
Content-Type: application/x-www-form-urlencoded

异常状况下的请求发送了 Accept-Encodeing: gzip服务器

2015-11-21 09:24:02.983959 IP 100.84.73.50.54462 > 100.84.73.34.9920: Flags [P.], seq 1:301, ack 1, win 115, options [nop,nop,TS val 3212551808 ecr 3054521289], length 300
E..`.+@.@.0udTI-dTI"..&..M.WPR.....s\J.....
.{....POST /Application/pullConfig HTTP/1.1
Host: 100.84.73.34:9920
Connection: Keep-Alive

正常状况下的请求没有发送 Accept-Encodeing: gzip网络

瞬间意识到是因为nginx将请求结果进行了gzip压缩,可是为什么有的业务能够正常处理,而又得业务获得结果为乱码。

向业务求证使用什么方式访问

无异常A业务答复:咱们使用Java的原生URL类进行请求。

有异常的B业务答复:咱们使用AsyncHttpClient进行请求。

查找AsyncHttpClient的使用,发现默认的方式是Accept-Encoding为gzip,可是须要在获取内容后,进行gzip解压。而B业务未进行相关的处理

这里有一篇文章讲的很好。http://www.cnblogs.com/TankXiao/archive/2012/11/13/2749055.html

深挖问题

B业务反馈其在部分状况下也是没有乱码的,看着具备随机性。为什么会这样?

深刻http gizp原理

翻阅nginx gzip的配置发现:gzip_min_length 配置,若是配置,则小于这个值不进行压缩,大于这个值进行压缩。

拓展学习

Nginx关于gzip的配置学习

  • gzip on; //该指令用于开启或关闭gzip模块(on/off)

  • gzip_min_length 1k; //设置容许压缩的页面最小字节数,页面字节数从header头得content-length中进行获取。默认值是0,无论页面多大都压缩。建议设置成大于1k的字节数,小于1k可能会越压越大。

  • gzip_buffers 4 16k; //设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。4 16k表明以16k为单位,安装原始数据大小以16k为单位的4倍申请内存。

  • gzip_http_version 1.1; //识别http的协议版本(1.0/1.1)

  • gzip_comp_level 2; //gzip压缩比,1压缩比最小处理速度最快,9压缩比最大但处理速度最慢(传输快但比较消耗cpu)

  • gzip_types text/plain application/x-javascript text/css application/xml //匹配mime类型进行压缩,不管是否指定,”text/html”类型老是会被压缩的。

  • gzip_vary on; //和http头有关系,加个vary头,给代理服务器用的,有的浏览器支持压缩,有的不支持,因此避免浪费不支持的也压缩,因此根据客户端的HTTP头来判断,是否须要压缩

相关文章
相关标签/搜索