nginx使用gzip压缩文件---lz77算法---Haffman编码

为了提高页面的响应速度,可以从设置 nginx 的 gzip 和缓存这2方面入手,而为ttf,js,css等文件开启 gzip 和缓存能大大减少带宽的消耗.

HTTP 的内容编码机制

Accept-Encoding 和 Content-Encoding 是 HTTP 中用来对[采用何种编码格式传输正文]进行协定的一对头部字段.
它的工作原理是这样:

浏览器发送请求时,通过 Accept-Encoding 带上自己支持的内容编码格式列表;
服务端从中挑选一种用来对正文进行编码,并通过 Content-Encoding 响应头指明选定的格式;
浏览器拿到响应正文后,依据 Content-Encoding 进行解压.
当然,服务端也可以返回未压缩的正文,但这种情况不允许返回 Content-Encoding;
这个过程就是 HTTP 的内容编码机制.

Accept-Encoding,作为请求首部字段,可以一次性指定多种内容编码,比如:

1.gzip由文件压缩程序gzip(GNU zip)生成的编码格式(RFC1952),采用Lempel-Ziv算法(LZ77)及32位冗余校验(Cyclic Redundancy Check,统称CRC);文章后面会统一介绍gzip的算法;
2.compress由UNIX文件压缩程序compress生成的编码格式,采用Lempel-Ziv-Welch算法(LZW);
3.deflate组合使用zlib格式(RFC1950)及由default压缩算法(RFC1951)生成的编码格式;
4.identity不执行压缩或者不会变化的默认编码格式.

Content-Encoding作为实体首部字段,采用的内容编码格式和Accept-Encoding是相对应的.

在nginx上添加以下逻辑,用来压缩字体文件,以达到节省网络带宽,提高网站速度的作用.

	#字体有很多格式,为匹配字体格式的文件进行压缩设置#就是拦截这种请求,然后压缩:www.test.com/dist/aabbccddeeffgg.ttflocation ~* ^/dist/.+\.(eot|ttf|otf|woff|svg)$ {#不缓存expires                 0;#增加type对应类型types {application/vnd.ms-fontobject eot;font/ttf ttf;font/opentype otf;font/x-woff woff;image/svg+xml svg;}# 开启gzipgzip  on;# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩gzip_min_length 1k;# 设置压缩所需要的缓冲区大小gzip_buffers 4 16k;#压缩版本(默认1.1,前端如果是squid2.5请使用1.0)gzip_http_version 1.0;#压缩等级 1-9 等级越高,压缩效果越好,节约宽带,但CPU消耗大gzip_comp_level 3;# 进行压缩的文件类型,默认就已经包含text/html。javascript有多种形式。其中的值可以在 mime.types 文件中找到。gzip_types font/ttf font/opentype font/x-woff image/svg+xml;# 是否在http header中添加Vary: Accept-Encoding,建议开启gzip_vary on;# 禁用IE 6 gzip , 因为IE6的某些版本对gzip的压缩支持很不好,会造成页面的假死gzip_disable "MSIE [1-6].";}

测试结果:

这里写图片描述

用curl测试gzip是否开启成功

curl -I -H "Accept-Encoding: gzip, deflate" "http://www.test.com/dist/aabbccddeeffgg.ttf"
gzip未开启:TP/1.1 200 OK
Server: JDWS/1.0.0
Date: Tue, 21 Aug 2018 01:49:24 GMT
Content-Length: 18520
Connection: close
Last-Modified: Mon, 20 Aug 2018 09:40:38 GMT
Accept-Ranges: bytes
Expires: Tue, 21 Aug 2018 01:49:24 GMT
Cache-Control: max-age=0
gzip开启:TP/1.1 200 OK
Server: JDWS/1.0.0
Date: Tue, 21 Aug 2018 01:48:10 GMT
Content-Type: font/ttf
Last-Modified: Fri, 10 Aug 2018 06:13:07 GMT
Connection: close
Vary: Accept-Encoding
Expires: Tue, 21 Aug 2018 01:48:10 GMT
Cache-Control: max-age=0
Content-Encoding: gzip

gzip压缩算法:

gzip是一种数据压缩格式,或者说是一种文件格式,用.gz结尾;
gzip可以极大的加速网站.有时压缩比率高达80%,一般最少都有40%左右;
对于要压缩的文件,使用gzip,主要分为两步:
1.使用LZ77压缩算法进行压缩,得到初始结果;
2.使用Haffman编码对初始结果进行再压缩,得到最终结果.

详细说下这两种算法:

LZ77算法

	这个算法是由Jacob Ziv 和 Abraham Lempel 于 1977 年提出,所以命名为 LZ77.整体思路:我们认为是一段内容总会有重复的内容,后面重复的内容可以用两者之间的距离加内容长度联合替换,而替换后的内容的所占空间一般都会比原内容小,重复越多,压缩完空间就越小.详细实现过程:先介绍三个概念:1.待编码区(字符从这里进来);2.已编码区(字符从这里出去,也叫缓冲区);3.滑动窗口(左边是已编码区,右边是待编码区,字符会从右向左依次被读取).|        滑动窗口       ||  已编码区   | 待编码区 ||             | a   a   b| c  b  b  a  b  c 再看看大概步骤:1.字符a从待编码区进来,此时a在待编码区的最左边;2.在待编码区查找从这个a字符在已编码区的最大匹配长度;3.如果能找到,就输出(偏移量m,最大匹配长度n),滑动窗口向右偏移n个位置;偏移量m就是待编码区的字符a到已编码区匹配到的字符a的移动距离;最大匹配长度n就是待编码区有多少连续字符可以在已编码区找到匹配的,这些连续字符的长度;4.如果找不到,就输出(0,0,a),滑动窗口向右偏移1位;5.直到待编码区为空,就停止编码,否则继续从2开始循环.

以上面的字符串为例,举个简单易懂的例子:
第一步:
a到待编码区的最左边了,在已编码区没有找到匹配的字符,输出(0,0,a),
如下图所示:
这里写图片描述
滑动窗口准备右移一位,到第二步.
第二步:
开始编码,待编码区的第一个字符是a,在已编码区查找匹配字符,找到了;
继续在待编码区读到ab两个字符,在已编码区查找匹配字符,没找到;
所以本次编码待编码区的第一个字符a,输出(1,1);
第一个1代表待编码区的a到已编码区的偏移量,偏移一位,记为1;
第二个1代表本次可编码的长度,因为只有一个a,所以记为1.
如下图所示:
这里写图片描述
滑动窗口准备右移一位,到第三步.
第三步:
待编码区第一个字符是b,在已编码区查找匹配字符,没找到;
同第一步,输出(0,0,b).
如下图所示:
这里写图片描述
滑动窗口准备右移一位,到第四步.
第四步:
待编码区第一个字符是c,在已编码区查找匹配字符,没找到;
同第一步,输出(0,0,c).
如下图所示:
这里写图片描述
滑动窗口准备右移一位,到第五步.
第五步:
待编码区第一个字符是b,在已编码区查找匹配字符,找到了;
待编码区前两个字符是bb,在已编码区查找匹配字符,没找到;
所以本次编码待编码区的第一个字符b,输出(2,1).
如下图所示:
这里写图片描述
滑动窗口准备右移一位,到第六步.
第六步:
待编码区第一个字符是b,在已编码区查找匹配字符,找到了;
待编码区前两个字符是ba,在已编码区查找匹配字符,没找到;
所以本次编码待编码区的第一个字符b,输出(3,1).
如下图所示:
这里写图片描述
滑动窗口准备右移一位,到第七步.
第七步:
待编码区第一个字符是a,在已编码区查找匹配字符,找到了;
待编码区前两个字符是ab,在已编码区查找匹配字符,找到了;
待编码区前三个字符是abc,在已编码区查找匹配字符,找到了;
这个例子待编码区只有三个字符的长度,实际会很长,就一直找,直到找不到匹配字符为止;
所以本次编码待编码区的前三个字符abc,输出(5,3).
如下图所示:
这里写图片描述
滑动窗口准备右移三位,到第八步.
第八步:
待编码区没有字符了,结束.
这里写图片描述

最终结果:
(0,0,a)(1,1)(0,0,b)(0,0,c)(2,1)(3,1)(5,3)
通过这个结果反向解码,也能得到原文:
aabcbbabc
而且解码比编码还要快很多,主要是因为少了匹配这一步.

Haffman编码

整体思路:我们知道,普通的编码都是定长的,比如ASCII编码,每个字符编码后的长度都是固定长度,
在解码的时候也就相对简单,只需按照定长将码解开,逐个翻译成对应的字符即可;而haffman采用的是可变长编码,目的是为了让出现次数多的字符采用更少的长度来存储,
这样就可能会大大加强压缩力度;haffman建立了树的概念,haffman树是一种二叉树,将所有符号都对应到树的叶子节点上,
每个叶子节点都是可以唯一表示的,都是用若干个0和1组成的;由于所有的字符最终都会落在叶子节点上,即任何字符的编码都不会是其他字符编码的前缀,
所以在解析的时候,也不会发生混淆的问题,因此haffman编码后的码,也是一种唯一可译码.详细实现过程:1.先读所有文件,将所有内容中所有字符出现的次数统计出来做排序;2.我们将出现少的两个字符作为子节点,可以确定一个父节点,值就是两个子节点的次数和;3.将上一步的父节点当做一个子节点,再重复执行第二步,直到所有节点全部用完,构成一颗大树;4.每个数从父节点开始,默认左边的子节点是0,右边的子节点是1,那么所有的字符对应的子节点都会有唯一的标识了;5.用这些唯一标识来代替原来的字符,就是编码后的结果;6.解码的时候,也是先根据所有字符的次数构成那颗大树,然后根据大树找出对应的字符即可.

举个简单易懂的例子:
比如文件的内容是:abbbbccccddde
我们可以统计出:
a出现1次;
b出现4次;
c出现4次;
d出现3次;
e出现1次;
第一步:
找出所有字符出现的次数.
如下图所示:
这里写图片描述
第二步:
找出两个最小次数的字符,构成一颗树;
a字符和e字符都只出现1次,次数最少,构成一颗树;
产生新的节点,个数为a和e次数的和,即为1+1=2.
如下图所示:
这里写图片描述
第三步:
再找出剩下的节点中出现次数最小的两个节点;
找出d字符和上一步的新节点,分别一个是3次,一个是2次;
这两个节点继续壮大这颗树,再产生新的节点,次数为3+2=5次.
如下图所示:
这里写图片描述
第四步:
再从剩下的节点中找出最小的两个,是b和c
构成新的树,父节点是4+4=8
如下图所示:
这里写图片描述
第五步:
将最后两个节点合并成一颗大树;
最上面是树的根节点;
最下面是每个字符对应的子节点;
我们默认为:从根节点自上向下看开始计数,往左拐记为0,往右拐记为1;
那么从根节点到下面每个子节点的路径所对应的计数的组合,就是这个字符所要代替的01组合.
如下图所示:
这里写图片描述
最终不难看出:
a对应110
b对应00
c对应01
d对应10
e对应111
那么原内容:abbbbccccddde
就可以替换为:1100000000001010101101010111
这个就是压缩后的内容,
那么在解压的时候,再将这些10的组合依次替换成对应的字符即可.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499994.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Javascript模块化编程

随着网站逐渐变成"互联网应用程序",嵌入网页的Javascript代码越来越庞大,越来越复杂。 网页越来越像桌面程序,需要一个团队分工协作、进度管理、单元测试等等......开发者不得不使用软件工程的方法,管理网页的业务逻辑。…

zookeeper基础整理

zookeeper简述 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件 ZooKeeper 使用 Java 所编写,但是支持 Java 和 C 两种编程语言。 提供的功能包括&#xf…

JS模块化编程require.js简介

一、为什么要用require.js? 最早的时候,所有Javascript代码都写在一个文件里面,只要加载这一个文件就够了。后来,代码越来越多,一个文件不够了,必须分成多个文件,依次加载。下面的网页代码&…

CSS position属性

目前几乎所有主流的浏览器都支持position属性("inherit"除外,"inherit"不支持所有包括IE8和之前版本IE浏览器,IE9、IE10还没测试过),以下是w3school对position五个值的解释: 其中absol…

storm的并行度的解释--- ( 看完就能理解 )

关于storm的基础,参照我这篇文章:流式计算storm 关于并发和并行,参照我这篇文章:并发和并行 关于storm的并行度解释,参照我这篇文章:storm的并行度解释 关于storm的流分组策略,参照我这篇文章:storm的流分组策略 关于storm的消息可靠机制,参照我这篇文章:storm的消息可靠机…

JS--Console.log()详解

对于JavaScript程序的调试,相比于alert(),使用console.log()是一种更好的方式,原因在于:alert()函数会阻断JavaScript程序的执行,从而造成副作用;而console.log()仅在控制台中打印相关信息,因此…

订单单量监控v2

前段时间做了一个订单单量监控的项目,已经投入使用了,现在总结一下 前期的想法参考这篇文章 整体使用了storm实时计算框架和redis数据库,还有kafka消息队列 先上效果图,我们可以后期将数据展示出来,明显发现某天00点有单量突变的情况,明显是促销活动导致单量增加了 而后面的报…

iOS中的MVC设计模式

一、MVC概述模型-视图-控制器(MVC)是Xerox PARC在二十世纪八十年代为编程语言Smalltalk-80发明的一种软件设计模式,已被广泛使用。后来被推荐为Oracle旗下Sun公司Java EE平台的设计模式,并且受到…

iOS-MVVM-模式介绍

一、MVVM概述 MVVM 到底是什么?我们首先看一下MVC架构:我们看到的是一个典型的 MVC 设置。Model 呈现数据,View 呈现用户界面,而 View Controller 调节它两者之间的交互。Cool!稍微考虑一下,虽然 View 和 …

[数据库]---mysql数据库 使用binlog+canal或binlake进行数据库的复制

前言 在进行冷热分离的时候,需要将数据实时的复制在历史数据库中,我们使用的是binlogcanal的思想,将每次数据库数据的变更转换成消息发出来,然后再操作这些消息达到数据复制的 在京东,实现同样功能的组件,叫binlake 接下来详细说下: 1.Binl…

MAC下配置ZSH

MAC下面的终端是神器。而且苹果非常贴心的为我们准备好了ZSH。 可惜ZSH不是很好用,需要配合一些插件和模板:oh-my-zsh将bash切换为zsh chsh -s /bin/zsh其实还可以用which来定位(特别是ubuntu的童鞋) chsh -s which zsh 直接用zsh…

MAC下使用OpenSSL生成私钥和公钥

MAC OS自带了OpenSSL,直接在命令行里使用OPENSSL就可以。打开命令行工具,然后输入 openssl打开openssl,接着只要三句命令就可以搞定。1、打开Terminal--cd 到指定文件夹,如桌面Mac:~/Desktop $ openssl2、第一句命令:生成私钥&…

idea插件开发(01)---最简单的helloworld版,不需要知道原理,先跟我做一个最简单的弹框插件

前言 用了那么多idea插件,也想自己做一个插件,下面就是入门版本 你不需要先知道所有的概念,先跟着我的步骤做一个小;例子,后面再说原理 相关概念看后面一篇 本次以windos系统为例 开始 1.你得安装一个环境,供idea插件的开发使用 下载地址: https://www.jetbrains.com/idea/…

苹果封装的对称加密和非对称加密API

一、信息摘要算法5&#xff1a;MD51.系统库位置&#xff1a;<CommonCrypto/CommonHMAC.h>。2.非加密算法&#xff0c;属于哈希散列&#xff0c;不可逆&#xff0c;用于检验数据完整性。二、安全散列(哈希)算法SHA&#xff1a; 1.包含的散列算法&#xff1a;SHA-1&#xf…

ECC椭圆曲线加密算法原理

比特币使用椭圆曲线算法生成公钥和私钥&#xff0c;选择的是secp256k1曲线。与RSA&#xff08;Ron Rivest&#xff0c;Adi Shamir&#xff0c;Len Adleman三位天才的名字&#xff09;一样&#xff0c;ECC&#xff08;Elliptic Curves Cryptography&#xff0c;椭圆曲线加密&…

AES加密算法原理

一、摘要 AES&#xff08;The Advanced Encryption Standard&#xff09;是美国国家标准与技术研究所用于加密电子数据的规范&#xff0c;在2002年5月26日建立。它被预期能成为人们公认的加密包括金融、电信和政府数字信息的方法。AES 是一个新的可以用于保护电子数据的加密算法…

Base64编码解码原理

一. Base64编码由来 为什么会有Base64编码呢&#xff1f;因为有些网络传送渠道并不支持所有的字节&#xff0c;例如传统的邮件只支持可见字符的传送&#xff0c;像ASCII码的控制字符就不能通过邮件传送。这样用途就受到了很大的限制&#xff0c;比如图片二进制流的每个字节不可…

eclipse mat 打开dump文件,明明大小1G,打开后却只有不到100M.其他的去哪了

eclipse mat 打开dump文件,明明大小1G,打开后却只有不到100M.其他的去哪了 Used heap dump 显示的大小远小于dump文件大小 解决: window-->Preferences-->memory Analuzer-->勾选keep unreachable objects-->apply and close

MVP模式介绍

一、概述MVP 是从经典的模式MVC演变而来&#xff0c;它们的基本思想有相通的地方&#xff1a;Controller/Presenter负责逻辑的处理&#xff0c;Model提供数据&#xff0c;View负责显示。二、MVC和MVP的区别作为一种新的模式&#xff0c;MVP与MVC有着一个重大的区别&#xff1a;…

VIPER模式介绍

一、概述VIPER模式的理念不属于MV(X)系类&#xff0c;其理念来自于建筑设计。建筑领域流行这样一句话&#xff0c;“我们虽然在营造建筑&#xff0c;但建筑也会重新塑造我们”。正如所有开发者最终领悟到的&#xff0c;这句话同样适用于构建软件。编写代码中至关重要的是&#…