1. 配置启用gzip 

vi conf/server.xml



<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
compression="on"
compressionMinSize="2048" noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" />



 

配置说明:

compression="on" 打开压缩功能 

compressionMinSize="2048" 启用压缩的最小内容大小,FileSize>=2048时才压缩

noCompressionUserAgents="gozilla, traviata" 对于以下的浏览器,不启用压缩 

compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" 启用压缩的资源类型

 

2. 测试gzip是否生效 

Tomcat是根据浏览器请求头中的accept-encoding来判断浏览器是否支持压缩功能,如果这个值包含有gzip,就表明浏览器支持gzip压缩内容的浏览,我们可以用两种方法来验证压缩是否生效。

 

2.1 请求原生内容



curl -I http://xxx:8080/protoweb/test.txt



 

Wireshark抓包分析:

Tomcat 启用gzip_抓包

 

Tomcat 启用gzip_抓包_02

 

抓包发现浏览器发送HTTP GET请求,随后接收到211个数据包,第211个包为HTTP 200结束包。请求该文件总耗时达5s。 

 

 

2.2 请求压缩内容


curl -H 'Accept-Encoding: gzip,deflate' -I http://xxx:8080/protoweb/test.txt


抓包发现与2.1发送数据包一致,压缩未生效?

谷歌搜索发现与NIO零拷贝有关,正如nginx会默认开启 sendfile on,Tomcat也是默认开启useSendfile="true",sendfile属性原型见Linux下系统调用sendfile(),sendfile()高效的原因是因为避免文件多次在内核态用户态间的拷贝(零拷贝方式),直接在内核中通过socket发送至网络。

WEB服务器启用压缩功能虽说可节省网络宽带,加快网络传输速度,但却对服务器带来了CPU压力,大文件压缩对服务器而言得不偿失。

Tomcat 默认>48kb,不启用压缩。

 

解决方案:

全局配置,关闭sendfile特性。


<Connector port="8080" protocol="HTTP/1.1"           connectionTimeout="20000"
redirectPort="8443"
useSendfile="false"
compression="on"
compressionMinSize="50" noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" />


 设置useSendfile=false。

 

sevlet配置:

限制sendfile文件大小。


<servlet> <init-param>
<param-name>sendfileSize</param-name>
<param-value>96</param-value>
</init-param>
</servlet>

 

由于是静态资源,采用全局配置关闭sendfile特性,测试:

Tomcat 启用gzip_抓包_03

 

 通过抓包发现,现在只有14个响应包,请求总耗时才0.06s,的确很快。