Nginx 的过滤模块是干啥用的?

上一篇文章我写了 Nginx 的 11 个阶段,许多人都说太长了。这是出于文章完整性的思量的,11 个阶段嘛,一次性说完就完事了。今天这篇文章对照短,看完没问题。

过滤模块的位置

之前我们先容了 Nginx 的 11 个阶段,在 content 阶段时,Nginx 会天生返回给用户的响应内容,对用户的响应内容,现实上还需要做再加工处置,Nginx 的过滤模块就是对响应内容举行再加工处置的。以是现实上过滤模块位于 content 阶段之后,log 阶段之前。

我们先来看一段设置指令:

limit_req zone=req_one
burst=120;
limit_conn c_zone 1;

satisfy any;
allow 192.168.1.0/32;
auth_basic_user_file access.pass;

gzip on;
image_filter resize 80 80;

那么在这一段设置指令之下,会遵照怎样的请求流程呢?请看一下下面这张图:

Nginx 的过滤模块是干啥用的?

上面这张图的流程大致说一下,若是对于 Nginx 的 11 个阶段不领会的去翻一下之前的文章。

我这里再简单说一下。首先由 Nginx 框架吸收 HTTP 请求,经由 preaccess、access、content 阶段的处置,当经由 static 模块之后天生响应的时刻,许多时刻需要对响应举行处置,然后才会返回给客户端。

这里我们如果响应是一张图片的话,那么需要做缩略图的时刻,首先就要经由 image_filter 模块的处置。这内里另有一个 gzip 模块,这两个模块也是需要遵照严酷的顺序的。由于若是先做 gzip 压缩的话,缩略图后面就没办法做了。

第二个需要关注的地方是,首先对 header 举行过滤,再对 body 举行过滤。由于我们在对用户发送响应的时刻,一定是先发送 header,然后再发送 body,以是所有的过滤模块都市提供对 header 或 body 的过滤,固然 image_filter 和 gzip 模块对这两者都可以过滤。

返回响应

前面我们说过,Nginx 的 11 个阶段是有严酷的顺序的,而这个顺序是在 Nginx 的代码中以一个数组的形式存在的,这个数组的顺序是从后往前。在给用户返回响应的时刻,过滤模块也是有严酷顺序的,这个顺序同样是从后往前。来看一下在代码中的界说,标红的是我下面会提到的几个过滤模块。

Nginx 的过滤模块是干啥用的?

我们需要重点关注四个过滤模块,它们划分的作用是啥呢?

  • copy_filter:复制包体内容

    当我们使用 sendfile 指令的时刻,也就是零拷贝手艺,不经由用户态内存,这里就是不经由 Nginx 直接发给用户,同时也用了 gzip 模块的时刻,gzip 是必须在 copy_filter 模块之后的,由于 gzip 必须对内存中的数据做压缩,这时 copy_filter 就会让 sendfile 指令失效。有些模块不需要对内存中的数据举行处置,就需要在 copy_filter 模块之前举行处置。

  • postpone_filter:处置子请求

    用来处置子请求,有些过滤模块需要关心子请求的处置结果,需要放在该模块之后。

  • header_filter:组织响应头部

    用来组织最终发送给用户的响应头部,可能会添加一些 Server,Nginx 版本号等内容。

  • write_filter:发送响应

    用来现实挪用操作系统的 write 或 send 等系统挪用,来把响应现实发送出去。

先容完了过滤模块的功效以及所处的阶段,下面来详细看两个模块。

sub 模块

先容一个可以替换响应中字符串内容的模块:sub 模块。

  • 功效:将响应中指定的字符串,替换成新的字符串
  • 模块:ngx_http_sub_filter_module 模块,默认未编译进 Nginx,通过 –with-http_sub_module 启用

指令

Syntax: sub_filter string replacement;
Default: —
Context: http, server, location

Syntax: sub_filter_last_modified on | off;
Default: sub_filter_last_modified off; 
Context: http, server, location

Syntax: sub_filter_once on | off;
Default: sub_filter_once on; 
Context: http, server, location

Syntax: sub_filter_types mime-type ...;
Default: sub_filter_types text/html; 
Context: http, server, location

来解释一下这四个指令都是啥意思。

  • sub_filter string replacement

    sub_filter 指令会把匹配到的 string 字符串替换成 replacement 示意的字符串。

    对 getopts 的理解

  • sub_filter_last_modified on | off

    sub_filter_last_modified 指令的意思是,是否要返回原来的 last_modified HTTP 头部,由于我们已经修改了文件内容,若是是 on 的话,就会继续返回原来的头部。

  • sub_filter_once on | off

    sub_filter_once 的意思是,是否只替换一次,默认打开,若是设置为 off 的话,那就会将响应中的内容所有扫描一遍并替换。

  • sub_filter_types mime-type

    这个指令是说针对那些文件类型举行替换,这里可以设置成 *,然则效率就会对照低了,需要凭据现实情况思量。

实战

设置文件如下:

server {
	server_name sub.ziyang.com;
	error_log  logs/myerror.log  info;
	
	location / {
    	sub_filter 'Nginx.oRg'  '$host/nginx';
    	sub_filter 'nginX.cOm' '$host/nginx';
    	#sub_filter_once on;
		sub_filter_once off;
		#sub_filter_last_modified off;
		sub_filter_last_modified on;
	}	
}

这里需要重新编译 Nginx,我这里把下一节需要的模块也一起编译进去了:

./configure --prefix=/Users/mtdp/myproject/nginx/test_nginx --with-http_sub_module --with-http_addition_module --with-http_realip_module
make
cp nginx ../../test_nginx/sbin/ # 复制编译好的 nginx 到之前的目录

执行热部署:

热部署的流程详见 Nginx 入门及命令行操作

kill -USR2 87693 # 使用新的 Nginx 二进制文件提供服务
kill -WINCH 87693 # 退出老的 Nginx 的 worker 历程
kill -quit 87693 # 优雅的退出老的 master 历程

在浏览器中打开 sub.ziyang.com:

Nginx 的过滤模块是干啥用的?

这内里会发现,nginx.org 已经替换成了 sub.ziyang.com/nginx,nginx.com 也替换成了 sub.ziyang.com/nginx。

addition 模块

下面再来看一个过滤模块,addition 模块,它可以在响应的前后添加内容。

  • 功效:在响应前或者响应后增添内容,增添内容的方式,是通过新增子请求,凭据子请求的响应来完成。

  • 模块:ngx_http_addition_filter_module

    默认未编译进 Nginx,通过 –with-http_addition_module 启用

指令

Syntax: add_before_body uri;
Default: —
Context: http, server, location

Syntax: add_after_body uri;
Default: —
Context: http, server, location

Syntax: addition_types mime-type ...;
Default: addition_types text/html; 
Context: http, server, location

这里的三个指令都对照简单,说一下 add_before_bodyadd_after_body 后面的 uri,这个的意思是说,向指定 uri 发起子请求,凭据子请求的响应来添加内容。

addition_types 指令是指定要添加的文件类型。

实战

设置文件如下:

server {
	server_name addition.ziyang.com;
	error_log logs/myerror.log info;
	
	location / {
    	#add_before_body /before_action;
    	#add_after_body  /after_action;
		#addition_types *;
	}	
	location /before_action {
		return 200 'new content before\n';
	}
	location /after_action {
		return 200 'new content after\n';
	}
	location /testhost {
		uninitialized_variable_warn on;
		set $foo 'testhost';
		return 200 '$gzip_ratio\n';
	}
}

先看在注释掉 addition 模块的指令的情况下,会是什么效果:

  ~ curl addition.ziyang.com/a.txt
a

然后打开注释:

  ~ curl addition.ziyang.com/a.txt
new content before
a
new content after

在原响应前后都增添了内容。

这内里需要注重一点,在现实情况下,add_before_bodyadd_after_body 后面是其他的 uri,我这里为了简化,直接转发到对应的 location。

本文涉及到的所有设置文件我已经放在了 Nginx 设置文件,人人可以自取。

本文首发于我的小我私家博客:iziyang.github.io

原创文章,作者:28x0新闻网,如若转载,请注明出处:https://www.28x0.com/archives/12178.html