天天看点

nginx反向代理模块配置详解_nginx反向代理模块

nginx反向代理模块配置详解_nginx反向代理模块

文字:

proxy模块

HTTP反向代理处理流程

proxy模块

功能:对上游服务器使用http/https协议进行反向代理。

语法:proxy_pass URL;

上下文:if,if in location

URL规则

必须以http或者https开头,接下来是域名|IP地址|Unix socket|upstream的名字。

域名和IP地址后边可以加端口。

最后可以带上可选的URI

URL参数中带有URI会导致法向上游的URL不同

不携带URI,则将客户端请求中的URL直接发送给上游服务器。

携带URI,则对用户请求中的URL做如下操作:

将location中匹配上的一段替换为该URI。

小例子:

upstreamproxyups {

server127.0.0.1:8012 weight=1;

keepalive2;

}

server{

set_real_ip_from  192.168.188.60;

real_ip_headerX-Forwarded-For;

listen8080;

location/a {

proxy_http_version1.1;

proxy_set_headerConnection"";

}

上例中,我配置上游服务器,返回$uri的内容。

上边proxy_pass的配置下:curl 192.168.188.60:8080/a/c,会输出 uri:/a/c,会原封不动地把URI发送给上游服务器。

如果上边第一个proxy_pass的注释打开,注释掉第二条。curl 192.168.188.60:8080/a/c,会输出:uri:/www/c,在location中先进行URI替换,然后再发送给上游服务器。

根据指令修改发往上游的请求

生成发往上游的请求行

proxy_method指令

语法:proxy_method method;

上下文:http,server,location。

作用:设置传给上游服务器的http请求的方法。

proxy_http_version

语法proxy_http_version  1.0|1.1

默认:proxy_http_version  1.0;

如果使用keepalive功能的时候,就必须使用proxy_http_version 1.1。

proxy_pass_requests_headers

作用:是否把用户请求的头部发给上游。如果设置为off,那么就不再把用户请求的header发给上游服务器了。

默认:proxy_pass_requests_headers  on;

proxy_pass_requests_body

作用:是否把用户请求的包体发给上游。

默认:proxy_pass_requests_body  on;

proxy_set_header

默认:proxy_set_header Host  $proxy_host;  proxy_set_header  Connection close;

作用:在上边proxy_pass_requests_headers为on的情况下,我可以自己设置传给上游服务器的header的头部内容。

proxy_set_body

作用:作用:在上边proxy_pass_requests_body为on的情况下,我可以自己设置传给上游服务器的body的内容。

小例子:

反向代理配置

upstreamproxyups {

server127.0.0.1:8012 weight=1;

}

server{

listen8080;

location/a {

proxy_methodPOST;

#               proxy_pass_request_headers off;

#               proxy_pass_request_body off;

proxy_set_headerHost'yang';

proxy_set_body'helow world';

proxy_http_version1.1;

proxy_set_headerConnection"";

}

}

上游服务器配置

server{

listen8012;

return200'8012 server response

uri:$uri

method:$request_method

request:$request

Host:$Host

http_name:$http_name\n';

}

执行测试命令:curl -H 'name:yudalihua' 192.168.188.60:8080/a/b

我在反向代理中设置的header能够直接显示出来,但是设置的body内容需要抓包才能看到,使用如下命令在8012端口抓包:tcpdump -i lo port 8012 -A -s 0  ,就能够看到在反向代理模块设置的body内容“hello  world”

接收用户请求包体的方式

proxy_request_bufferring

默认:proxy_request_bufferring on;

当设置为on的情况

客户端网速比较慢

上游服务并发处理能力低

适应高吞吐量的场景。

当设置为off的情况

更及时的响应

降低nginx读写磁盘的消耗。

一旦开始发送内容,proxy_next_upstream指令失效。

client_body_buffer_size

默认:client_body_buffer_size 8k|18k

原理:

在接收header的时候,可能会接收到部分body。

判断接收到的body是否已经是所有的body。

如果已经接收完了body,则不分配client_body_buffer

若剩余待接收包体长度小于client_body_buffer_size,则仅分配所需要的。

否则,我们就分配client_body_buffer_size 大小的内存,用于接收客户端的body。不管用户的body是1G还是多大,我们都是通过这么大小的缓存,一段一段地收。

client_body_in_single_buffer

client_max_body_size

默认:client_max_body_size  1m;

客户端body的最大长度,默认是1M,非常小,不够用。

作用:针对请求头部中含有Content-length时,如果其字段超过了client_max_body_size,就返回413错误。

client_body_temp_path

默认:client_body_temp_path  client_body_temp;

client_body_in_file_only

语法:client_body_in_file_only on|clean| off;

默认:client_body_in_file_only off;

如果设置为on:

那么客户端的请求的body会被一直保存在文件中,方便我们定位问题。

如果设置为off:

那么客户端处理完body之后,可能该文件就被删除了。

client_body_timeout:

语法:client_body_timeout time;

默认:client_body_timeout 60s;

作用:两次读取body之间的最大时延,如果读取包体超过了最大时延,返回408错误。

与上游服务建立连接

proxy_connect_timeout

默认:proxy_connect_timeout  60s;

和上游建立TCP连接的超时时间。

如果超时了,上游肯定是没有响应的,那么nginx会生成一个502的响应码。

proxy_next_upstream http_502

作用:如果超时,或者其他原因,和一个上游服务器建立TCP连接出现错误,那么就选择另一个upstream进行尝试。

proxy_socket_keepalive

默认:proxy_socket_keepalive  off;

作用:反向代理和上游服务是否开启TCP的keepalive功能。

上下文:http,server,location。

TCP的keepalive

判断TCP连接的对方是否存在,如果不存在,就及时关闭,减少资源的浪费。

keepalive

语法:keepalive connections

上下文:upstream

keepalive_requests

语法:keepalive_requests number;

默认:keepalive_requests 100;

上下文:upstream

proxy_bind

语法:proxy_bind  address [transparent] |off;

address

address可以使用变量,例如$remote_addr

address可以使用非本机地址,但是必须加上transparent关键字。

作用:就是修改请求报文的IP头部中的source  IP Address为我们指定的IP地址。

proxy_ignore_client_abort

默认:proxy_ignore_client_abort off;

如果设置为on:

当客户端到反向代理的连接断开的时候,忽略这种情况,不断开反向代理同上游服务器的连接。

会给上游带来很大的性能压力。

如果设置为 off:

当客户端和nginx断开连接的时候,nginx和上游服务器也断开连接。

默认为off。

proxy_send_timeout

默认:proxy_send_timeout  60s;

把请求发送给上游服务器,后请求的超时时间。

接收上游的响应

proxy_buffer_size

默认:proxy_buffer_size  4k|8k;

作用

限制了反向代理可以接收的上游的最大header,如果上游返回的响应有cookie等非常大的数据,可能会导致整个header超出了nginx处理的能力。

会报错,在错误日志文件中生成:upstream sent  too big header

proxy_buffering

默认:proxy_buffering  on;

如果设置为ON

那么nginx接收上游的服务发送来的响应body,会先缓存起来,然后再发送出去。

默认设置为ON,因为nginx和上游服务器都是在内网中,网速非常快。而nginx和客户端直接网速要慢很多,如果发送一个很大的body的话,那么会导致nginx和上游服务器有长时间的连接。而上游服务,比如Django,或者Tomcat的并发能力是非常弱的。

表明我们想要快速释放nginx和上游服务器之间的连接。

proxy_buffers

语法:proxy_buffers  number  size;

默认:proxy_buffers 8  4k|8k;

作用:

上个指令缓存上游的响应body的时候,要写到磁盘,就需要进行IO。

试想,如果我们不把上游的body放到磁盘中,而是放到缓存中可以吗?

这就是这个指令的效果,默认分配8个4k大小的缓存,也就是32k,如果这个缓存能够放下上游的body,就放到缓存中;否则,还是会向磁盘中写。

proxy_max_temp_file_size

默认:proxy_max_temp_file_size 1024m;

作用:

当把上游响应body写到磁盘的时候,限制这个磁盘文件大小的最大值。

如果超出了阈值,也会出错。

proxy_temp_write_sze

默认:proxy_temp_write_sze  8k|16k;

作用:当把上游的body写入磁盘的时候,每一次写磁盘,写进去的单位,一次8k或者16k。

proxy_temp_path

默认:proxy_temp_path  proxy_temp;

作用:把上游的body写入磁盘时候,文件的路径。

proxy_busy_buffers_size

默认:proxy_busy_buffers_size  8k|16k;

作用:

及时转发body。

当从上游接收一个很大的response body的时候,会先把它写到磁盘或者缓存,但是每写好8k或者16k,就像客户端发送一次。

proxy_read_timeout

默认:proxy_read_timeout 60s;

作用:TCP层的概念,两次读取之间的超时时间是60秒,如果超过了这个事件,TCP连接应该就会断开了。

proxy_limit_rate

默认:proxy_limit_rate 0;

作用

限制读取上游响应的速度。

设置为0,表示不限制。

proxy_store

如果设置为on

nginx接收上游的响应body生成的临时文件,我们可以做持久化处理。

默认开启。

proxy_store access

设置上边持久化文件的访问权限。

小例子:

nginx配置

server{

listen8080;

root/tmp;

location/a {

proxy_storeon;

proxy_store_accessuser:rw group:rw all:r;

}}

上游服务配置

server{

listen8012;

location/ {

roothtml;

}

}

curl 192.168.188.60:8080/a.txt   这个命令上游服务给我把a.txt文件发送过来了,按道理说我也设置了持久化了,但是不知道为什么,就是在nginx的机器上看不到把temp文件持久化的结果。

处理上游的响应

proxy_ignore_headers  field ...;

功能:上游服务器的某些响应头可能会改变nginx的行为。这个指令可以让指定的响应头失效。

可以禁用功能的头部:

proxy_hide_header  field;

功能:对于上游响应中的某些头部,设置默认不对客户端转发。

proxy_cookie_domain

proxy_cookie_path

上边两个指令都是nginx修改从上游服务器返回的Set-Cookie头部

proxy_redirect

nginx修改从上游服务器返回的响应中的location头部。

上游出现失败时的容错方案

proxy_next_upstream

前提:上游没有向客户端发送任何内容,哪怕一个字节。

配置:

error

与上游建立连接、读取响应、发送请求,等等,任何一个环境出现了错误,都可以满足条件,激活这个 命令。

timeout

命中 connetc_timeout 、 read_timeout等情景,会激活这个命令,重新选取一个upstream

invalid_header

收到的上游的HTTP的header是不合法的。

http_

可以跟一个明确的响应code。

可以根据这样的一个code去选择另一个upstream

off

不开启这个指令。

proxy_next_upstream_timeout

开始选用另一个upstream,直到选中某个upstream的超时时间。

proxy_next_upstream_tries

如果设置为0,表示不再限制。

小例子一:

nginx的配置

upstreamnextups {

server127.0.0.1:8012 weight=1;

server127.0.0.1:8011 weight=1;

}

server{

listen8080;

location/ {

proxy_connect_timeout1s;

proxy_next_upstream off;

}

上游服务器的配置

server{

listen8011;

return200'8011 server response\n';

}

server{

listen8014;

return200'8012 server response\n';

}

上边nginx中的upstream配置了两个服务,分别在8011和8012端口;我上游服务器没有开8012端口。

proxy_next_upstream 的值:

如果是off,执行curl 192.168.188.60:8080,可能会出错,因为请求还是会被分发到8012端口上,nginx可能等一定时间,就会向不存在的端口上发送请求,就会返回错误。

如果是error,当执行curl 192.168.188.60:8080时,不会返回错误,请求都被分发到了8012端口上了。

小例子二、

nginx的配置

server{

listen8080;

location/httperr {

proxy_next_upstream http_500;

}

上游服务的配置

server{

listen8011;

return200'8011 server response\n';

}

server{

listen8012;

return500'8012 system error\n';

}

执行curl 192.168.188.60:8080/httperr 命令,返回根据proxy_next_upstream的值

如果为http_500

那么所有的curl结果,都是8011 server response

如果为off,或者注释掉这一行

那么curl结果就是8011 server response 或者 8012 system error

proxy_intercept_errorson|off

默认为off。

作用:当上游响应的响应码>=300时,应该把响应返回客户端还是按照error_page指令处理。

总之来说,就是用error_page来拦截上游失败指令。

小例子:

nginx配置。

server{

listen8080;

error_page 500/a.txt;

location/intercept {

proxy_intercept_errorson;

}

}

上游服务器配置

server{

listen8012;

return500'8012 system error\n';

}

上边设置了proxy_intercept_errors为on,那么curl 192.168.188.60:8080/intercep,上游服务器会返回500,这个500,被error_page拦截,进而执行了error_page的指令。

注意:error_page只能拦截返回值和他后边code一样的响应。