有时候客户端和服务器之间会传输比较大的报文数据,这时候就占用较大的网络带宽和时长。为了节省带宽,加速报文的响应速速,能够将传输的报文数据先进行压缩,而后再进行传输。
HTTP支持多种报文压缩算法,下面是一个普通的请求头,从Accept-Encoding字段能够看出支持gzip、deflate和br压缩算法。本文咱们重点讲使用Gzip算法对报文进行压缩,好比Gzip来压缩HTML,Javascript, CSS文件,压缩完后能大大减小网络传输的数据量,提升了用户显示网页的速度。javascript
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 Cache-Control: max-age=0 Connection: keep-alive Host: localhost:8000 If-Modified-Since: Tue, 21 Apr 2020 14:09:01 GMT If-None-Match: "5e9efe7d-264" Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
任何技术都是双面的,HTTP压缩虽然能减小带宽占用加快响应速度,可是由于须要额外的压缩和解压的过程,因此会占用些客户端或服务器端的计算资源。css
了解HTTP的读者知道,能够对HTTP的报文体进行编码加密。其实HTTP压缩是一种特殊的编码方式,使用这种编码方式能够将报文大大减小,使用对应的解法方式又能还原最初的报文。(咱们能够看出,其实压缩技术的本质就是一种编码方式)html
从上面对于HTTP压缩的介绍能够看出,这种技术是一种优化技术,经常用于压缩服务器端返回的报文以达到节省带宽加速响应的目的。java
下面简单介绍一个HTTP使用Gzip压缩的过程。nginx
浏览器发送Http request 给Web服务器, request 中有Accept-Encoding: gzip, deflate, br。 (告诉服务器,浏览器支持gzip压缩)web
Web服务器接到request后, 先生成原始的Response, 其中有原始的Content-Type和Content-Length。正则表达式
Web服务器经过Gzip,来对Response进行编码, 编码后header中有Content-Type和Content-Length(压缩后的大小), 而且增长了Content-Encoding:gzip. 而后把Response发送给浏览器。算法
浏览器接到Response后,根据Content-Encoding:gzip来对Response进行解码。 获取到原始response后, 而后显示出网页。spring
客户端也能够发送压缩数据给服务端,经过代码将请求数据解压便可,规范起见一样要在请求中加入Content-Encoding:gzipjson
Nginx提供了对HTTP Gzip压缩的支持,这边咱们就来看看适应Nginx怎么对返回报文进行压缩。
Nginx中经过ngx_http_gzip_module模块、ngx_http_gzip_static_module模块和ngx_http_gunzip_module模块来对Gzip功能进行支持。通常状况下Nginx默认会编译
这些模块,能够经过nginx -V命令看下你安装的nginx是否包含了这些模块。
Gzip相关的指令能够在配置文件的http块、server块或者location块中。
ngx_http_gzip_module模块主要负责Gzip功能的开启和设置,对响应数据进行在线实时压缩。该模块包含如下主要指令。
# 开启或者关闭Gzip功能,默认状况下,该指令设置为off,即不启用Gzip功能。只有将该指令设置为on时,其余指令设置才有效 gzip on | off # 设置Gzip压缩文件使用缓存空间的大小 # 默认值是:gzip_buffers 32 4k|16 8k gzip_buffers number size; # 该指令用于设定Gzip压缩程度,包括级别1到级别9。 # 级别1表示压缩程度最低,压缩效率最高;级别9表示压缩程度最高,压缩效率最低,最费时间。 # 默认是1 gzip_comp_level level # 针对不一样种类客户端发起的请求,能够选择性地开启和关闭Gzip功能。 # 支持正则表达式,其中,regex 根据客户端的浏览器标志(User-Agent,UA)进行设置。 gzip_disable regex ...; # 该设置使用了正则表达式,其能够匹配UC字符串中包含MSIE 四、MSIE 5和MSIE6的全部浏览器。 # 响应这些浏览器发出的请求时,Nginx服务器不进行Gzip压缩。 gzip_disable MSIE [4-6]\.; # 早期的一些浏览器或者HTTP客户端,可能不支持Gzip自解压,所以用户有时会看到乱码,因此针 # 对不一样的HTTP协议版本,须要选择性地开启或者关闭Gzip功能。该指令用于设置开启Gzip功能的最低HTTP协议版本。 # 默认设置为1.1版本,即只有客户端使用1.1及以上版本的HTTP协议时,才使用Gzip功能对响应输出数据进行压缩。 # 从目前来看,绝大多数的浏览器都支持Gzip自解压,通常采用默认值便可. zip_http_version 1.0 | 1.1; # 该指令设置页面的字节数,当响应页面的大小大于该值时,才启用Gzip功能。 # 建议设置成gzip_min_length 1024; gzip_min_length length; # 用于设置Nginx服务器是否对后端服务器返回的结果进行Gzip压缩; # 通常状况下,后端都是用来作restAPI接口,返回的数据量不会太大,不建议进行压缩 # 真的须要对后端返回的数据进行压缩是能够再看下这块的内容 gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any ...; # 设置MIME类型,被设置的类型将被压缩,默认值是:text/html # 该变量还能够取“*”,表示对全部MIME类型的页面数据进行Gzip压缩 # 通常能够设置成:gzip_types text/plain application/javascript text/css text/xml gzip_types mime-type ...; # 开启后的效果是在响应头部添加了Accept-Encoding: gzip gzip_vary on | off;
ngx_http_gzip_static_module模块主要负责搜索和发送通过Gzip功能预压缩的数据。这些数据以“.gz”做为后缀名存储在服务器上。若是客户端请求的数据在以前被压缩过,而且客户端浏览器支持Gzip压缩,就直接返回压缩后的数据。
该模块与ngx_http_gzip_module模块的不一样之处主要在于,该模块使用的是静态压缩,在HTTP响应头部包含Content-Length头域来指明报文体的长度,用于服务器可肯定响应数据长度的状况;然后者默认使用Chunked编码的动态压缩,其主要适用于服务器没法肯定响应数据长度的状况,好比大文件下载的情形,这时须要实时生成数据长度。
该模块指令的使用和ngx_http_gzip_static_module模块相似,这边就再也不具体展开了。你们能够参考官方文档
该模块是Nginx服务器的可选HTTP模块,若是要使用,必须在Nginx程序配置时添加--with-http_gzip_static_module指令。
Nginx服务器支持对响应输出数据流进行Gzip压缩,这对客户端浏览器来讲,须要有能力解压和处理Gzip压缩数据,但若是客户端自己不支持该功能,就须要Nginx服务器在向其发送数据以前先将该数据解压。这些压缩数据可能来自于后端服务器压缩产生或者Nginx服务器预压缩产生。ngx_http_gunzip_module模块即是用来针对不支持Gzip压缩数据处理的客户端浏览器,对压缩数据进行解压处理的.
一样,对这个模块的指令使用就不具体展开了,你们能够参考官方文档
现代的浏览器通常都支持压缩功能,因此这个模块使用到的概率较小。
gzip on; gzip_min_length 1000; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain application/xml;
为了使得Nginx服务器可以在全局范围内应用Gzip压缩功能,能够将Gzip配置放在了http全局块中。若是要对各个虚拟主机差异性对待,咱们能够在对应的server
块中添加各自的Gzip配置指令;
平时开发的应用中可能不是全部的应用都使用了Nginx,看看其余Web服务器怎么开启对HTTP压缩的支持。
1. Spring Boot中内嵌的Tomcat开启压缩功能
Tomcat做为servet容器+http server,也是支持gzip压缩的。使用传统的Tomcat的话,咱们只须要在server.xml配置开启HTTP压缩便可。
在embed版本下须要经过代码来配置。spring-boot内置的tomcat是embed版本,经过内置的autoconfig机制已经作了一些默认tomcat配置,可是对于一些不经常使用/高级的配置,spring-boot并无提供入口。
不过因为spring bean的特性,能够覆盖默认装配的bean,包括tomcat相关的配置。使用TomcatConnectorCustomizer接口能够开启压缩配置。
public class ConnC1 implements TomcatConnectorCustomizer{ @Override public void customize(Connector connector) { ProtocolHandler protocolHandler = connector.getProtocolHandler(); if(protocolHandler instanceof Http11NioProtocol){ Http11NioProtocol http11NioProtocol = (Http11NioProtocol)protocolHandler; http11NioProtocol.setCompression("on");//default off http11NioProtocol.setCompressibleMimeType(); http11NioProtocol.setCompressionMinSize(2048);//default 2048(B) http11NioProtocol.setMaxKeepAliveRequests(1);//default 200 } } }
关于Tomcat对于HTTP压缩的支持,你们能够从Tomcat的CompressionConfig这个类开始寻找线索。
其实若是只是简单开启对压缩功能的支持的话,只要在Spring Boot作下面的配置便可:
server: compression: enabled: true min-response-size: 1024 mime-types: application/json
欢迎你们留言说说Gzip功能还有哪些经常使用场景~