Nginx(3)之反向代理及相关指令

Nginx(3)之反向代理及相关指令

微信搜索 zze_coding 或扫描 👉 二维码关注我的微信公众号获取更多资源推送:

实例一

目标

打开浏览器,在浏览器地址栏输入地址 www.123.com,跳转到 linux 系统中 tomcat 主页面。

步骤

1、安装并启动 tomcat,使用默认的 8080 端口,tomcat 下载:https://pan.baidu.com/s/1f1KAlNEsVnI6jRXry05DPA

注意,要确定防火墙开放了 8080 端口,并且使用浏览器测试访问能成功。

2、在本地 hosts 文件(C:\Windows\System32\drivers\etc\hosts)中添加配置:

192.168.202.132 www.123.com

上面配置中的 IP 是 Nginx 主机的 IP。

3、修改 http 块下的 server 块的 server_name 值为 www.123.com,在同级下的 location 块中添加如下配置:

proxy_pass http://127.0.0.1:8080;

该配置的含义就是让 Nginx 监听着域名为 www.123.com 端口为 80 的请求,让该请求转发到主机本地的 http://127.0.0.1:8080,即 tomcat 服务。

4、访问测试。

实例二

目标

Nginx 监听域名为 www.123.com 端口为 8888 的请求:

  • 请求 www.123.com:8888/tomcat1 时返回占用 8081 端口的 tomcat 主页;
  • 请求 www.123.com:8888/tomcat2 时返回占用 8082 端口的 tomcat 主页;
  • 请求 www.123.com:8888/tomcat3 时返回占用 8083 端口的 tomcat 主页;

步骤

1、启动三个 tomcat 服务,分别监听端口 808180828083
2、在 Nginx 配置文件中添加如下 server 配置:

server {
    listen       8888;
    server_name  www.123.com;
   
    location ^~/tomcat1/ {
        proxy_pass http://127.0.0.1:8081/;
        root   html;
        index  index.html index.html
    }

    location ^~/tomcat2/ {
        proxy_pass http://127.0.0.1:8082/;
        root   html;
        index  index.html index.htm;
    }

    location  ^~/tomcat3/ {
        proxy_pass http://127.0.0.1:8083/;
        root   html;
        index  index.html index.htm;
    }
}

注意,在该配置中 proxy_pass 值的后面是有一个 / 的,表示转发到对应 proxy_pass 的根路径,而如果没有这个 /,原请求前缀也会添加到转发的路径。
例, 有一个请求为 www.123.com/tomcat1

  • proxy_passhttp://127.0.0.1:8081 时,相当于转发到 http://127.0.0.1:8081/tomcat1
  • proxy_passhttp://127.0.0.1:8081/,相当于转发到 http://127.0.0.1:8081/

3、访问测试。

补充指令

设定头部

proxy_set_header 指令用来设定代理转发请求的请求头信息,其使用规则如下:

语法:proxy_set_header field value;
默认值:proxy_set_header Host $proxy_host;
	proxy_set_header Connection close;
可使用的上下文:http, server, location

由其默认值可以看出,代理主机转发请求时会将源地址设定为代理主机地址($proxy_host),举个例子:

有如下三台主机:
	客户端:10.0.1.200;
	代理主机:10.0.1.201;
	后端主机:10.0.1.202;

客户端发送请求到代理主机,代理主机转发请求到后端主机。
由于代理主机默认会修改源地址为自身(10.0.1.201),所以后端主机看到的就一直是代理主机(10.0.1.201)请求自己。

即默认情况下被代理后端主机时获取不到真实的客户端地址的。
在上面这个例子中,如果后端主机想要获取到客户端地址该怎么办呢?

哈哈,我们可以在代理主机转发请求时将源客户端地址保存到请求头中,然后后台主机就可以通过对应的变量来获取到对应的请求头,也就的获取到了源客户端地址。

这里有如下两个请求头及其对应的变量就是专门用来解决这个问题的:

请求头对应变量描述
proxy_set_header X-Real-IP $remote_addr;$http_x_real_ip仅保存代理主机上一级地址。
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;http_x_forwarded_for+= 的方式保存多级代理地址,多个地址以 , 隔开,适用于追踪多级代理源地址。

在上面描述的例子里,只有一级代理,所以通过请求头 X-Real-IP 就可以记录到源客户端地址,但如果要记录多级代理地址,就需要使用请求头 X-Forwarded-For 了。

还有一个 proxy_hide_header 指令专门用来隐藏向客户端响应的头部,使用规则如下:

语法: proxy_hide_header field;
默认值: —
可使用的上下文: http, server, location

默认情况下,Nginx 不会将代理服务器的响应中的标头字段 DateServerX-PadX-Accel-...”传递给客户端。
还可以 proxy_hide_header 指令设置不传递的其他字段。

相反,如果需要允许指定标头字段从代理服务器传递到客户端,则可以使用 proxy_pass_header 指令,其使用规则如下:

语法: proxy_pass_header field;
默认值: —
可使用的上下文: http, server, location

还要补充说明的一点是,请求经过 Nginx 代理转发后使用的 HTTP 协议版本默认为 1.0,如果要指定转发请求使用的 HTTP 协议版本,可使用 proxy_http_version 指令,例:

proxy_http_version 1.1;

设定超时时间

如下几个指令可以设定代理服务器指定状态的超时时间,很简单,就直接列出用法了:
1、代理服务器与后端服务器连接超时时间设定:

语法: proxy_connect_timeout time;
默认值: proxy_connect_timeout 60s;
可使用的上下文: http, server, location

2、代理服务器等待后端服务器响应的超时时间设定:

语法: proxy_read_timeout time;
默认值: proxy_read_timeout 60s;
可使用的上下文: http, server, location

3、后端服务器数据回传给代理服务器的超时时间设定:

语法: proxy_send_timeout time; 
默认值: proxy_send_timeout 60s; 
可使用的上下文: http, server, location

缓冲区设定

如果启用的缓冲区,那么代理服务器会把后端返回的内容先放到缓冲区当中,然后再返回给客户端。
1、启用缓冲区:

语法: proxy_buffering on | off;
默认值: proxy_buffering on;
可使用的上下文: http, server, location

2、设置代理服务器保存用户头信息的缓冲区大小:

语法: proxy_buffer_size size; 
默认值: proxy_buffer_size 4k|8k; 
可使用的上下文: http, server, location

3、设定代理服务器响应内容的缓冲区:

//proxy_buffers 缓冲区
Syntax: proxy_buffers number size; 
Default: proxy_buffers 8 4k|8k; 
Context: http, server, location

平滑过渡

语法: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | non_idempotent | off ...;
默认值: proxy_next_upstream error timeout;
可使用的上下文: http, server, location

proxy_next_upstream 指令可用来指定在何种情况下请求应该被传递到下一个服务器,这个“情况”的可选值有如下:

  • error:在与服务器建立连接、向其传递请求或读取响应标头时发生错误;
  • timeout:与服务器建立连接,向服务器传递请求或读取响应标头时发生超时;
  • invalid_header:服务器返回了空的或无效的响应;
  • http_500:服务器返回响应状态码 200;
  • http_502:服务器返回响应状态码 502;
  • http_503:服务器返回响应状态码 503;
  • http_504:服务器返回响应状态码 504;
  • http_403:服务器返回响应状态码 403;
  • http_404:服务器返回响应状态码 404;
  • http_429:服务器返回响应状态码 429;
  • non_idempotent:通常,如果请求已发送到上游服务器(1.9.13),则 POST,LOCK,PATCH 方法的请求不会传递到下一服务器。明确启用此选项将允许重试此类请求;
  • off:禁用将请求传递到下一个服务器;

与之对应的还有一个指令为 proxy_next_upstream_timeout,该指令语法如下:

语法: proxy_next_upstream_timeout time;
默认值: proxy_next_upstream_timeout 0;
可使用的上下文: http, server, location

该指令出现在 1.7.5 版本。

该指令用来限定请求传递给下一个服务器的超时时间。

除此之外,还可使用 proxy_next_upstream_tries 指令限定传递到下一个服务器的尝试次数,其使用规则如下:

语法: proxy_next_upstream_tries number;
默认值: proxy_next_upstream_tries 0;
可使用的上下文: http, server, location

该指令出现在 1.7.5 版本。

包含配置

可以将多处要使用的相同指令提取出来保存在一个文件中,如下:

$ vim /etc/nginx/proxy_params
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;

然后在要使用的配置节中可以通过 include 指令将其包含进来即可生效,如:

location / {
    ...
    include proxy_params;
}

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.zze.xyz/archives/nginx3.html

Buy me a cup of coffee ☕.