Nginx系列:數(shù)據(jù)壓縮
閱讀文本大概需要3分鐘。
? ? ? 【Nginx系列:Nginx源碼安裝】中源碼安裝Nginx時(shí),講到需要安裝zlib和zlib-devel是因?yàn)閮蓚€(gè)庫提供了壓縮功能,而Nginx的ngx_http_gzip_module模塊就是使用這兩個(gè)庫進(jìn)行數(shù)據(jù)壓縮的。
? ? ? ? ?gzip是nginx服務(wù)器的ngx_http_gzip_module模塊提供的在線實(shí)時(shí)數(shù)據(jù)壓縮功能。通過開啟gzip功能,可對(duì)服務(wù)器響應(yīng)的數(shù)據(jù)進(jìn)行壓縮處理,變成體積更小的二進(jìn)制文件。在高PV的網(wǎng)站應(yīng)用中,可以節(jié)省海量的帶寬。
? ? ? 如圖所示,客戶端瀏覽器發(fā)出的請(qǐng)求頭中聲明了支持gzip類型的壓縮文件,若服務(wù)器端開啟了gzip壓縮功能,那么響應(yīng)數(shù)據(jù)會(huì)經(jīng)過壓縮后再返回客戶端,由客戶端負(fù)責(zé)解壓縮后再進(jìn)行數(shù)據(jù)渲染。

0x01:Nginx壓縮相關(guān)參數(shù)
gzip on | off;
Nginx支持對(duì)指定類型的文件進(jìn)行壓縮然后再傳輸給客戶端,而且壓縮還可以設(shè)置壓縮比例,壓縮后的文件大小將比源文件顯著變小,有助于降低出口帶寬的利用率,降低企業(yè)的IT支出,不過會(huì)占用相應(yīng)的CPU資源。
gzip?on;?
參數(shù)來啟用壓縮,默認(rèn)是關(guān)閉的。
gzip_comp_level lenvel;
壓縮比例由低到高從1到9,默認(rèn)為1。但需要注意的是壓縮比設(shè)置的越高就會(huì)越消耗CPU的資源,因此在生產(chǎn)環(huán)境中我們會(huì)設(shè)置該參數(shù)的值在3~5之間,最好不要超過5,因?yàn)殡S著壓縮比的增大的確會(huì)降低傳輸?shù)膸挸杀镜l(fā)送數(shù)據(jù)前會(huì)占用更多的CPU時(shí)間分片。
具體設(shè)置級(jí)別為多少,得運(yùn)維人員對(duì)CPU的利用率做一個(gè)監(jiān)控,如果CPU利用率過低則不會(huì)使用,可以酌情將壓縮級(jí)別參數(shù)調(diào)大,當(dāng)然調(diào)大后依舊需要觀察一段業(yè)務(wù)高峰期時(shí)間CPU的利用率,最終會(huì)找到一個(gè)適合的壓縮比例。
gzip_disable "MSIE [1-6]\.";
? ? ?禁用IE6 gzip功能。
gzip_min_length 1k;
? ? gzip壓縮的最小文件,小于設(shè)置值的文件將不會(huì)壓縮
gzip_http_version 1.0|1.1;
啟用壓縮功能時(shí),協(xié)議的最小版本,默認(rèn)HTTP/1.1
gzip_buffers number size;
指定Nginx服務(wù)需要向服務(wù)器申請(qǐng)的緩存空間的個(gè)數(shù)*大小,默認(rèn)32 4k|16 8k;
gzip_types mine-type ...;
? ? ?除text/html外,還對(duì)指定的MIME類型啟用響應(yīng)的壓縮。特殊值“?*”匹配任何MIME類型(0.8.29)。text/html類型的響應(yīng)始終被壓縮。
gzip_vary on| off;
如果啟用壓縮,是否在響應(yīng)報(bào)文首部插入“Vary: Accept-Encoding”,建議開啟該參數(shù),讓用戶知道服務(wù)端是支持壓縮功能。
推薦查看官網(wǎng)說明
https://nginx.org/en/docs/http/ngx_http_gzip_module.html
0x02:SpringBoot項(xiàng)目準(zhǔn)備
在進(jìn)行Nginx負(fù)載均衡配置前,先搭建一個(gè)簡(jiǎn)單的后端應(yīng)用項(xiàng)目:nginx-upstream
pom.xml文文件
<project?xmlns="http://maven.apache.org/POM/4.0.0"?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
????xsi:schemaLocation="http://maven.apache.org/POM/4.0.0?http://maven.apache.org/xsd/maven-4.0.0.xsd">
????<modelVersion>4.0.0modelVersion>
????<groupId>com.sentinelgroupId>
????<artifactId>nginx-upstreamartifactId>
????<version>0.0.1-SNAPSHOTversion>
????<packaging>jarpackaging>
????<parent>
????????<groupId>org.springframework.bootgroupId>
????????<artifactId>spring-boot-starter-parentartifactId>
????????<version>2.1.3.RELEASEversion>
????????<relativePath/>?
????parent>
????<name>nginx-upstreamname>
????<url>http://maven.apache.orgurl>
????<properties>
????????<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
????????<java.version>1.8java.version>
????properties>
????<dependencies>
????????<dependency>
????????????<groupId>org.springframework.bootgroupId>
????????????<artifactId>spring-boot-starter-webartifactId>
????????dependency>
????dependencies>
????<dependencyManagement>
????????<dependencies>
????????????<dependency>
????????????????<groupId>org.springframework.cloudgroupId>
????????????????<artifactId>spring-cloud-dependenciesartifactId>
????????????????<version>Greenwich.SR3version>
????????????????<type>pomtype>
????????????????<scope>importscope>
????????????dependency>
????????dependencies>
????dependencyManagement>
project>
控制器controller
該控制器返回一個(gè)txt文件里的數(shù)據(jù),其中這個(gè)文件的大小如下圖

package?com.olive.controller;
import?java.io.ByteArrayOutputStream;
import?java.io.FileInputStream;
import?java.io.FileNotFoundException;
import?java.util.HashMap;
import?java.util.Map;
import?org.springframework.web.bind.annotation.GetMapping;
import?org.springframework.web.bind.annotation.RestController;
@RestController
public?class?UserController?{
????@GetMapping("/getUser")
????public?Map<String,?Object>?getUser()?{
????????Map<String,?Object>?result?=?new?HashMap<>();
????????result.put("code",?"000000");
????????result.put("message",?"ok");
????????try?{
????????????FileInputStream?in?=?new?FileInputStream("d:/a.txt");
????????????ByteArrayOutputStream?out?=?new?ByteArrayOutputStream();
????????????int?len?=-1;
????????????byte[]?b?=?new?byte[1024];
????????????while((len=in.read(b))!=-1){
????????????????out.write(b,?0,?len);
????????????}
????????????result.put("body",?new??String(out.toByteArray()));
????????}?catch?(Exception?e)?{
????????????e.printStackTrace();
????????}
????????return?result;
????}
}application.yml配置文件
server:
??port:?8866
spring:
??application:
????name:?nginx-upstream
SpringBoot啟動(dòng)類
package?com.olive;
import?org.springframework.boot.SpringApplication;
import?org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public?class?Application?{
????public?static?void?main(String[]?args)?{
????????SpringApplication.run(Application.class,?args);
????}
}
啟動(dòng)項(xiàng)目,驗(yàn)證是否搭建成功

0x03:配置Nginx
先把上篇的8867這臺(tái)服務(wù)器注釋,因?yàn)楸酒婚_啟了8866這臺(tái)服務(wù)器。

在沒有開啟壓縮時(shí),即配置項(xiàng)為
gzip?off;
訪問Nginx,返回的數(shù)據(jù)的大小跟直接訪問Springboot項(xiàng)目的8866端口的大小是一模一樣的。

開啟Nginx的壓縮功能,在Nginx的配置文件nginx.conf添加如下配置項(xiàng)
????#?在http上下文中添加gzip配置
????gzip??on;
????gzip_buffers?32?4K;
????gzip_comp_level?6;
????gzip_min_length?200;
????gzip_types?application/json;
重啟Nginx,再次訪問Nginx

可以看到開啟壓縮后,返回?cái)?shù)據(jù)的大小僅有8.7K,比沒有開啟壓縮的數(shù)據(jù)大小1.4M,小了非常大。
附錄:
【Nginx系列:負(fù)載均衡】文件少了Controller部分代碼,具體代碼如下
package?com.olive.controller;
import?java.util.HashMap;
import?java.util.Map;
import?org.springframework.web.bind.annotation.GetMapping;
import?org.springframework.web.bind.annotation.RestController;
@RestController
public?class?UserController?{
????@GetMapping("/getUser")
????public?Map<String,?Object>?getUser()?{
????????Map<String,?Object>?result?=?new?HashMap<>();
????????result.put("code",?"000000");
????????result.put("message",?"ok");
????????result.put("body",?"我是服務(wù)器8866");
//????????result.put("body",?"我是服務(wù)器8867");
????????return?result;
????}
}
☆
往期精彩
☆
01?Sentinel如何進(jìn)行流量監(jiān)控
02?Nacos源碼編譯
03?基于Apache Curator框架的ZooKeeper使用詳解
關(guān)注我
每天進(jìn)步一點(diǎn)點(diǎn)
