Nginx正向代理和反向代理

大致的概念

代理服务,也称为正向代理服务。
如果把局域网外Internet想象成一个巨大的资源库,那么资源就分布在Internet的各个站点上,局域网内的客户端要访问这个库里的资源必须统一通过代理服务器才能对各个站点进行访问。
也就是说正向代理服务器不支持外部对内部网络的访问请求。

与正向代理相反,如果局域网向Internet提供资源,让Internet上的其他用户可以访问局域网内的资源,也可以设置使用一个代理服务器,它提供的服务就叫反向代理服务。

正向代理服务器用来让局域网客户机接入外网以访问外网资源,反向代理服务器用来让外网的客户端接入局域网中的站点以访问点中的资源。

Nginx配置正向代理

resolver 指令 :指定DNS服务器的IP地址。

resolver address ... [valid=time]

参数解析:
address : DNS服务器的IP地址。如果不指定端口号,默认使用53端口。
time : 设置数据包在网络中的有效时间。这个命令的主要原因是,在访问站点时,有很多情况使得数据包在一定时间内不能被传递到目的地,但是又不能让该数据包无限制的存在,于是就需要设定一段时间,当数据包在这段时间内没有到达目的地,就会被丢弃,然后发送者会接收到一个消息,并决定是否要重发该数据包。

resolver 127.0.0.1 [::1]:5353 valid=30s

resolver_timeout 指令:该指令用于设置DNS服务器域名解析超时时间。

resolver_timeout 30s;

proxy_pass 指令:该指令用于设置代理服务器的协议和地址,它不仅仅用于Nginx服务器的代理服务,更主要用于反向代理。

proxy_pass http://$http_host$request_uri;

正向代理配置例子:

server { resolver 8.8.8.8; listen 82; location / { proxy_pass proxy_pass http://$http_host$request_uri;

注意:server块中 不要设置 server_name 指令,既不要设置虚拟主机的名称或者IP。但是resolver 指令是必须的,如果没有这个指令,Nginx服务器无法处理接收到的域名。

Nginx反向代理配置

1. proxy_pass 指令:用来设置被代理服务器的地址,包括传输协议、主机名称或者IP地址加端口号、URI等要素。还可以接受以“unix”开始的UNIX-domain套接字路径。

proxy_pass http://www.xxx.com/uri;
proxy_pass http://localhost:8080/uri;
proxy_pass http://unix:/tmp/backend.socket:/uri/;

代理一组服务器例子:

.....
# 配置后端服务器组
upstream my_proxy {
    server http://192.168.1.1:8001;
    server http://192.168.1.2:8001;
    server http://192.168.1.4:8001;
    # server http://192.168.1.3:8001/uri/;
server {
   listen 80;
   server_name www.myweb.com;
   location / {
      proxy_pass my_proxy;
.....

注意:使用这个 proxy_pass 指令的时候,如果代理的URL中是否包含了URI,Nginx服务器处理方式都不相同。如果URL中不包含URI,Nginx服务器不会改变原地址的URI;但是如果包含了URI,Nginx服务器将会使用新的URI代替原来的URI。
看下面例子:

比如指定了URI

server {
   listen 80;
   server_name www.myweb.com;
   location / {
      proxy_pass http://192.168.1.1:8001/loc/;

那么请求 “http://www.my.com/server/” 发起请求,,Nginx服务器会把地址转向 "http://192.168.1.1:8001/loc/" 就把 "/server/" 替换掉为 "/loc/"

比如没有指定了URI

server {
   listen 80;
   server_name www.myweb.com;
   location / {
      proxy_pass http://192.168.1.1:8001;

那么请求 “http://www.my.com/server” 发起请求,,Nginx服务器会把地址转向 "http://192.168.1.1:8001/server", 原有的URI不变

proxy_pass 指令的URL末尾是否加 "/" 的问题:

proxy_pass http://192.168.1.1; proxy_pass http://192.168.1.1/;

测试实例1:

server {
   listen 80;
   server_name www.myweb.com;
   location / {
      proxy_pass http://192.168.1.1;
      proxy_pass http://192.168.1.1/;

在这个配置中 localhost 块使用 "/" 作为 uri 变量的值来匹配不包含URI的请求URL。由于请求URL中不包含URI,因此配置1 和 配置 2 的效果一样。比如 "http://www.myweb.com/index.html",配置1 和 配置2 都会转向到 "http://192.168.1.1/index.html"

测试实例2:

server {
   listen 80;
   server_name www.myweb.com;
   location /server/ {
      proxy_pass http://192.168.1.1;
      proxy_pass http://192.168.1.1/;

在这个配置中,localhost块使用 “/server/” 作为 uri 变量的值来匹配包含URI “/server/” 的请求URL。
这时候使用配置1 和 配置2 的转向结果就不一样了。使用配置1的时候,不会改变原地址的URI;使用配置2的时候,proxy_pass 指令中的URI变量包含了URI “/”,Nginx服务器就会将原地址的URI替换为“/”.
比如 "http://www.myweb.com/server/index.html",使用配置2的时候,会转向到 "http://192.168.1.1/index.html",原地址的 /server/ 会被替换掉!

proxy_pass 在上面所述的替换URI的问题, 所替换的URI是针对 localhost 匹配的URI替换。
localhost /server/ { 
  proxy_pass http://127.0.0.1:8080/ 

那么请求 http://www.xxxx.com/server/name/index.html 的时候,只会把 /server/ 给 截断/替换 掉,不会把 /name 给 截断/替换 掉!最终 http://www.xxxx.com/server/name/index.html 变成 http://127.0.0.1:8080/name/index.html

2. proxy_hide_header 指令:该指令用于设置Nginx在发送HTTP响应时,隐藏一些头域信息。
该指令可用于 http块、server块或者localhost块

proxy_hide_header field;

3. proxy_pass_header 指令:默认情况下,Nginx服务器发送响应报文时,报文头信息中不包含 "Date"、"Server"、"X-Accel"等来自被代理服务器的头域信息。该指令可以设置这些头域信息以被发送。

proxy_pass_header field;

4. proxy_pass_request_body 指令:用于配置是否将客户端请求的请求头发送给代理服务器。

proxy_pass_request_body on | off;

默认设置为开启(on),可以在http块、server块或者location块中进行配置。

5. proxy_pass_request_headers 指令:指令用于配置是否将客户端请求的请求头发送给代理服务器。

proxy_pass_request_headers on | off;

默认设置为开启(on),开关可以在http块、server块或者localhost块中进行配置。

6. proxy_set_header 指令:指令可以更改Nginx服务器接收到的客户端请求的请求头信息,然后将新的请求头发送给被代理的服务器。

proxy_set_header field value;

field 要更改的信息所在的头域
value 更改的值

默认情况下,该指令的设置为:

proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
proxy_set_header Host $http_host; # 将目前Host头域的值填充成客户端的地址
proxy_set_header Host $host; # 将目前localtion 块的 server_name指令值填充到Host头域
proxy_set_header Host $host:$proxy_port; # 将目前localtion 块的 server_name指令值和listener指令值填充到Host头域

7.proxy_set_body 指令 :可以更改Nginx服务器接收到的客户端请求的请求体信息,然后将新的请求体发送给被代理的服务器。

proxy_set_body value;

value 支持使用文本、变量或者变量的组合

8.proxy_bind 指令 :强制将与代理主机的连接绑定到指定的IP地址。通俗来讲就是,在配置了多个基于名称或者基于IP的主机的情况下,如果我们希望代理连接由指定的主机处理,就可以使用这个配置。

proxy_bind  address;

address 为主机的IP地址
注意:Nginx 版本在0.8.22 及 以上支持该指令。

9.proxy_connect_timeout 指令:指令配置Nginx服务器与后端被代理服务器尝试建立连接的超时时间。

proxy_connect_timeout time;

time 为设置的超时时间,默认为 60s

10.proxy_read_timeout指令:指令配置Nginx服务器向后端被代理服务器(组)发出read请求后,等待响应的超时时间。

proxy_read_timeout time;

time 为设置的超时时间,默认为 60s

11.proxy_send_timeout指令:指令配置Nginx服务器向后端被代理服务器(组)发出write请求后,等待响应的超时时间。

proxy_send_timeouttime;

time 为设置的超时时间,默认为 60s

12.proxy_http_version 指令:用于设置Nginx服务器提供代理服务的HTTP协议版本。

proxy_http_version 1.0 | 1.1;

13.proxy_method 指令:用于设置Nginx服务器请求被代理服务器时使用的请求方法,一般为POST 或者 GET。设置了该指令,客户端的请求方法将被忽略。

proxy_method method;

method 的值可以设置为 POST 或者 GET

14.proxy_ignore_client_abort 指令:用于设置在客户端中断网络请求时,Nginx服务器是否中断对被代理服务器的请求。

proxy_ignore_client_abort on | off;

默认设置为 off,当客户端中断网络请求时,Nginx服务器中断对代理服务器的请求。

可配置的指令太多了,就不一一列出来了。

均衡负载配置

主要使用proxy_pass指令和upstream指令

配置一:对请求一般轮询

.....
# 配置后端服务器组
upstream my_proxy {
    # 默认 weight = 1
    server http://192.168.1.1:8001;
    server http://192.168.1.2:8001;
    server http://192.168.1.4:8001;
server {
   listen 80;
   server_name www.myweb.com;
   location / {
      proxy_pass my_proxy;
.....

配置二:对请求进行加权轮询

.....
# 配置后端服务器组
upstream my_proxy {
    # 默认weight = 1
    server http://192.168.1.1:8001 weight = 5;
    server http://192.168.1.2:8001 weight = 2;
    server http://192.168.1.4:8001;
server {
   listen 80;
   server_name www.myweb.com;
   location / {
      proxy_pass my_proxy;
.....

配置三:对特定资源实现均衡负载

.....
# 配置后端服务器组
upstream video_proxy {
    # 默认weight = 1
    server http://192.168.1.1:8001;
    server http://192.168.1.2:8001;
    server http://192.168.1.4:8001;
# 配置后端服务器组
upstream file_proxy {
    # 默认weight = 1
    server http://192.168.1.5:8001;
    server http://192.168.1.6:8001;
    server http://192.168.1.7:8001;
server {
   listen 80;
   server_name www.myweb.com;
   # 针对 video 请求
   location /video/ {
      proxy_pass video_proxy;
   # 针对 file 请求
   location /file/ {
      proxy_pass file_proxy ;
.....

配置四:针对不同域名实现均衡负载

.....
# 配置后端服务器组
upstream bbs_proxy {
    # 默认weight = 1
    server http://192.168.1.1:8001;
    server http://192.168.1.2:8001;
    server http://192.168.1.4:8001;
# 配置后端服务器组
upstream home_proxy {
    # 默认weight = 1
    server http://192.168.1.5:8001;
    server http://192.168.1.6:8001;
    server http://192.168.1.7:8001;
server {
   listen 80;
   server_name www.myHome.com;
   location / {
      proxy_pass home_proxy;
server {
   listen 81;
   server_name www.myBbs.com;
   location / {
      proxy_pass bbs_proxy ;