nginx 压缩大法

Posted 灰极客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nginx 压缩大法相关的知识,希望对你有一定的参考价值。

nginx为什么要有压缩

        正如大家所知道的nginx是一个web server,它经常作为网络接入层被使用,无论是IDC接入还是CDN接入,常常都用nginx作为接入,IDC就是机房源站;CDN就是做动态加速的,类似于快递公司~,本人就是快递员,哈哈,回归正题,继续说nginx,而且nginx是一个开源软件,方便开发者开发第三方module,各大互联网公司也很青睐nginx,因为nginx为他们节省了一大批钱(不用买昂贵的交换机做接入)。

        当然,每家公司都希望能够以最小的代价实现最大化利益,说白了就是为他们省钱,哈哈,一般省钱的方式有两种,一个是提高负载能力,即提高单台机器的负载能力;另一个是节省带宽,这个是最重要的,因为现在带宽很贵的,详情可以咨询三大运营商,而压缩正好能够为公司节省特别多的带宽,所以,在网络接入层进行压缩很有必要,即在 nginx上压缩。

 

nginx压缩

        nginx原生支持gzip压缩,当然现在也有第三方module支持br压缩等等,本文主要讲解gzip压缩‘。

        nginx gzip 压缩有三大module:

  1. ngx_http_gzip_static_module

    1. 这个模块的作用是如果客户端请求服务器上的静态文件,而这个文件和nginx在同一个机器上,那么nginx会把它,压缩成“.gz”后缀结尾的文件,然后再发送给客户端,这个在静态cdn可能会用到

  2. ngx_http_gzip_module

    1. 这个模块是用来将nginx后端返回的http response body,压缩成gzip格式,然后在发送给客户端的,这个能够极大的节省服务器的带宽的,这个是今天讲的核心module

  3. ngx_http_gunzip_module   

    1. 这个模块是当客户端不支持gzip的时候,nginx会把已经压缩成gzip格式的response body,解压成原始数据,这个module不常用。

            接下来详细说下ngx_http_gzip_module,这个module是在filter phase执行,ngx_http_gunzip_module也是在filter phase执行,至于执行的顺序,就看他两编译的时候是按什么顺序编译的。

           ngx_http_gzip_module其实是在filter 阶段早起执行的,filter阶段有很多模块,这个只是其中一个模块,另外filter是由 top_header_filter和top_body_filter两个函数链表串联起来的,当然,这两链表最终都是走的write_filter handler里,由它通过socket发给客户端哈。

            ngx_http_gzip_module会在 header filter阶段判断时候后端已经压缩了,如果已经压缩,那么nginx,就不会再进行压缩,如果没压缩则会进行压缩, nginx header filter代码如下:

    static ngx_int_tngx_http_gzip_header_filter(ngx_http_request_t *r){ ngx_table_elt_t *h; ngx_http_gzip_ctx_t *ctx; ngx_http_gzip_conf_t *conf;
    conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module);
    if (!conf->enable || (r->headers_out.status != NGX_HTTP_OK && r->headers_out.status != NGX_HTTP_FORBIDDEN && r->headers_out.status != NGX_HTTP_NOT_FOUND) || (r->headers_out.content_encoding && r->headers_out.content_encoding->value.len) /* 这个就是判断后端是否进行了压缩的条件 */ || (r->headers_out.content_length_n != -1 && r->headers_out.content_length_n < conf->min_length) || ngx_http_test_content_type(r, &conf->types) == NULL || r->header_only) { return ngx_http_next_header_filter(r); } ......    /* 添加压缩response header,客户端用得着 */    ngx_str_set(&h->key, "Content-Encoding"); ngx_str_set(&h->value, "gzip"); r->headers_out.content_encoding = h;

    ...... }


        接下来再看一下 top_body_filter里的内容,这个阶段是真正要把http response body进行压缩,代码如下:

        /* 将数据从ngx_buf_t 复制到 gzip的输入缓冲buffer里 */rc=ngx_http_gzip_filter_add_data;/* 为gzip的输出buffer申请内存 */rc = ngx_http_gzip_filter_get_buf(r, ctx);/* data 真正开始压缩,他是调用的zlib的deflate function,大家有兴趣可以看看 */rc = ngx_http_gzip_filter_deflate(r, ctx);/* 这个函数里会有gzip数据格式的haeader字段和尾部crc32校验字段,这个两个字段客户端解压要用所以必须要有 */



        最后,两大filter链表将数据处理完之后,会将数据返回给client。

        感想大家花时间来看,发一个招聘信息,招CDN方向的专家,base 北京,感兴趣可以把简历发我邮箱 zhangjinde@kuaishou.com ,公司老铁们应该都知道,欢迎志同道合的朋友们一起玩耍国内顶尖CDN技术~


以上是关于nginx 压缩大法的主要内容,如果未能解决你的问题,请参考以下文章

AJAX相关JS代码片段和部分浏览器模型

Nginx——Nginx启动报错Job for nginx.service failed because the control process exited with error code(代码片段

开启Nginx的gzip压缩功能详解

Nginx静态压缩和代码压缩,提高访问速度!

PostgreSQL 是不是支持表(片段)的透明压缩?

nginx/express 开启gzip压缩