HTTP 请求 / 响应压缩是一种用于减少在客户端和服务器之间传输的数据量的技术。它通过对 HTTP 消息(包括请求头、请求体、响应头和响应体)中的数据进行压缩,然后在接收端进行解压缩,从而提高数据传输效率。
内容协商阶段:在客户端发起请求时,会在请求头中通过 Accept-Encoding 字段告知服务器它所支持的压缩算法,如 gzip、deflate 等。例如,一个请求头可能包含 Accept-Encoding: gzip, deflate,这表示客户端能够接受使用 gzip 或者 deflate 算法进行压缩的内容。
服务器处理阶段:服务器接收到请求后,根据自身的配置和客户端请求的压缩算法偏好,对响应内容进行压缩。如果服务器支持请求中的压缩算法,它会将响应数据进行压缩,并在响应头中通过Content-Encoding 字段告知客户端使用了哪种压缩算法。例如,Content-Encoding: gzip 表明响应内容是用 gzip 算法压缩的。
客户端接收阶段:客户端收到带有压缩数据的响应后,根据 Content-Encoding 字段指示的压缩算法对数据进行解压缩,然后再进行后续的处理,如渲染网页、解析数据等。
带宽成本降低:对于网站运营者来说,网络带宽是一项重要的成本支出。通过压缩数据,可以在相同的带宽条件下传输更多的内容。
提高网络性能:在网络带宽有限的情况下,压缩数据能够加快内容的传输速度。特别是对于移动网络用户或者网络连接较慢的区域,减少数据传输量可以让网页加载更快,降低用户等待时间。
优化传输效率:在网络传输过程中,数据传输的速度取决于多个因素,其中数据量大小是一个关键因素。较小的数据量可以在更短的时间内完成传输。
提升服务器性能:从服务器的角度来看,由于压缩后的数据量变小,服务器能够更快地将数据发送出去,这样可以减少服务器的负载。
客户端节能:对于移动设备等客户端来说,接收和处理的数据量越小,消耗的电量就越少。因为设备在下载和处理数据时,如通过无线通信模块接收数据、对数据进行解压缩和渲染等操作都需要消耗电量。
服务器节能:在服务器端,减少数据传输量也意味着服务器在数据传输过程中消耗的能量降低。当服务器需要处理大量请求时,较低的能源消耗有助于降低运营成本,同时也符合节能环保的理念。
该示例将演示开启请求/响应压缩功能。
在 Spring Boot 项目中,可以通过如下配置开启服务端压缩功能,如下:
server: compression: # 启用压缩功能 enabled: true # 配置要压缩的 mime-type 列表 mime-types: application/json,text/html,text/xml,text/plain # 设置最小响应大小,低于该大小则不开启压缩,单位字节 min-response-size: 1
同理,在配置客户端项目的配置 application.yml 文件中添加如下配置,开启请求响应压缩功能:
spring: cloud: openfeign: compression: request: # 开启请求压缩 enabled: true # 请求最小大小,低于该大小,则不进行压缩,单位字节 min-request-size: 2 # 允许压缩的 mime 类型列表 mime-types: text/plain,text/xml,application/xml,application/json response: # 开启响应压缩 enabled: true
当完成上述服务端和客户端压缩配置后,重启两个服务。调用任意一个接口,输出日志如下:
[AdvancedFeign#demo4] ---> GET http://SERVICE-DEMO/simple/info HTTP/1.1 [AdvancedFeign#demo4] Accept-Encoding: gzip [AdvancedFeign#demo4] Accept-Encoding: deflate [AdvancedFeign#demo4] ---> END HTTP (0-byte body) [AdvancedFeign#demo4] <--- HTTP/1.1 200 (289ms) [AdvancedFeign#demo4] connection: keep-alive [AdvancedFeign#demo4] content-encoding: gzip [AdvancedFeign#demo4] content-type: text/plain;charset=UTF-8 [AdvancedFeign#demo4] date: Mon, 11 Nov 2024 14:45:34 GMT [AdvancedFeign#demo4] keep-alive: timeout=60 [AdvancedFeign#demo4] transfer-encoding: chunked [AdvancedFeign#demo4] vary: accept-encoding [AdvancedFeign#demo4] [AdvancedFeign#demo4] appName=service-demo appPort=8090 uuid=10c178b9-d350-4ef8-849d-7d996e4caecc [AdvancedFeign#demo4] <--- END HTTP (75-byte body)
上述日志中,请求部分添加了 Accept-Encoding: gzip 和 Accept-Encoding: deflate 请求头,响应部分添加了 content-encoding: gzip 请求头,说明成功开启了压缩功能。
💥注意:由于 OkHttpClient 使用 "transparent"(透明) 压缩,即存在 content-encoding 或 accept-encoding 头的情况下禁用,所以当 feign.okhttp.OkHttpClient 出现在 classpath 上并且 spring.cloud.openfeign.okhttp.enabled 被设置为 true 时,我们不会启用压缩。