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:
ngx_http_gzip_static_module
这个模块的作用是如果客户端请求服务器上的静态文件,而这个文件和nginx在同一个机器上,那么nginx会把它,压缩成“.gz”后缀结尾的文件,然后再发送给客户端,这个在静态cdn可能会用到
ngx_http_gzip_module
这个模块是用来将nginx后端返回的http response body,压缩成gzip格式,然后在发送给客户端的,这个能够极大的节省服务器的带宽的,这个是今天讲的核心module
ngx_http_gunzip_module
这个模块是当客户端不支持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_t
ngx_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 压缩大法的主要内容,如果未能解决你的问题,请参考以下文章
Nginx——Nginx启动报错Job for nginx.service failed because the control process exited with error code(代码片段