Nginx是非常强大的反向代理服务器,经常用于前置机上进行路由转发,静态资源反向代理等。
在服务端开发过程中,为了方便,我们会希望直接能够访问本地的服务器,便于调试,但是本地服务器是外网访问不了的,这个时候,我们可以通过修改外网的nginx配置,通过添加特定的url规则,反向代理到本地,这样外网的访问也能送到本地进行处理了。
这种反向代理的方法在工作中非常方便,我们甚至可以用 Nginx 反向代理到Tomcat服务器,进行本地Java服务端的开发。
可以通过 Nginx 中转,把特定的请求,从服务器转发到本地,或者在服务器之间转发,进行处理。
一定要注意反向代理的匹配规则在配置中是否最优先,下面介绍的路径匹配的优先级是很低的,可以使用 ^~ 来提高优先级进行匹配。
proxy_pass 代理
反向代理的相关配置需要在 Location 模块中进行配置,把匹配的请求进行反向代理,转发到 proxy_pass 配置的服务器进行处理。
此配置项将当前请求反向代理到 URL 参数指定的服务器上,URL可以是主机名或IP地址加端口的形式。
proxy_pass URL; # example location /uewx/ { index index.jsp index.html index.php; proxy_pass http://192.168.119.62:8080/ConfigService/uewx/; }
这里的IP地址 192.168.119.62 是我本地的局域网IP,通过在我的测试服务器的Nginx配置中加上这一句,就可以把外网进来的 /uewx 的请求转发到我本地的Tomcat服务器进行处理,真的非常方便。
通过上面例子简单的 proxy_pass 配置,就可以把 /uewx 的请求转发到 http://192.168.119.62:8080/ConfigService/uewx/ 进行处理,在进行配置的过程中,要注意 URL 后面的斜杠。
针对斜杠问题,下面针对访问地址: http://test.local_nginx.com/proxy/test.html 进行说明:
location /proxy/ { proxy_pass http://192.168.119.62/; } # 代理到 http://192.168.119.62/test.html location /proxy/ { proxy_pass http://192.168.119.62; # 代理URL没有/ } # 代理到 http://192.168.119.62/proxy/test.html location /proxy/ { proxy_pass http://192.168.119.62/proxy/; # 代理URL包含匹配,包含/ } # 代理到 http://192.168.119.62/proxy/test.html location /proxy/ { proxy_pass http://192.168.119.62/proxy; # 代理URL包含匹配,缺少/ } # 代理到 http://192.168.119.62/proxytest.html
这里的URL还可以结合 upstream 负载均衡进行配置:
# 负载均衡配置
upstream backend {
server backend1.com weight=5;
server backend2.com:8080;
}
server {
location / {
proxy_pass http://backend;
}
}
默认情况下反向代理是不会转发请求中的Host头部的。如果需要转发,那么必须加上配置:
proxy_set_header Host host;
# 下面的配置用于向后台服务器转发请求来源IP
proxy_set_header X-Real-IPremote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
其他可选代理配置
Nginx的反向代理模块提供了很多种配置,如设置转发请求过程中的行为、连接的超时时间、临时文件如何存储,以及最重要的如何缓存上游服务器响应等功能。以下的配置可以放在:http、server、location模块。
Nginx反向代理的配置可以参考官方文档:http://nginx.org/en/docs/http/ngx_http_proxy_module.html 下面介绍一些常用的配置。
proxy_method
语法:proxy_method method;
此配置项表示转发时的协议方法名。GET请求在转发时方法名会改为POST。
proxy_method POST;
proxy_hide_header
语法:proxy_hide_header the_header;
Nginx会将上游服务器的响应转发给客户端,但默认不会转发以下HTTP头部字段:Date、Server、X-Pad和X-Accel-*。使用proxy_hide_header后可以任意地指定哪些HTTP头部字段不能被转发。例如:
proxy_hide_header Cache-Control; proxy_hide_header MicrosoftOfficeWebServer;
proxy_pass_header
语法:proxy_pass_header the_header;
与proxy_hide_header功能相反,proxy_pass_header会将原来禁止转发的header设置为允许转发。例如:
proxy_pass_header X-Accel-Redirect;
proxy_pass_request_body
语法:proxy_pass_request_body on | off;
默认:proxy_pass_request_body on;
作用为确定是否向上游服务器发送HTTP包体部分。
proxy_pass_request_headers
语法:proxy_pass_request_headers on | off;
默认:proxy_pass_request_headers on;
作用为确定是否转发HTTP头部。
proxy_redirect
语法:proxy_redirect [ default|off|redirect replacement ];
默认:proxy_redirect default;
当上游服务器返回的响应是重定向或刷新请求(如HTTP响应码是301或者302)时,proxy_redirect可以重设HTTP头部的location或refresh字段。
例如,如果上游服务器发出的响应是302重定向请求,location字段的URL是:http://localhost:8000/two/some/uri/,那么在下面的配置情况下,实际转发给客户端的location是http://frontend/one/some/uri/。
proxy_redirect http://localhost:8000/two/ http://frontend/one/;
这里还可以使用ngx-http-core-module提供的变量来设置新的location字段。例如
proxy_redirect http://localhost:8000/ http://host:server_port/;
也可以省略replacement参数中的主机名部分,这时会用虚拟主机名称来填充。例如:
proxy_redirect http://localhost:8000/two/ /one/;
使用off参数时,将使location或者refresh字段维持不变。例如:
proxy_redirect off;
使用默认的default参数时,会按照proxy_pass配置项和所属的location配置项重组发往客户端的location头部。例如,下面两种配置效果是一样的:
location /one/ { proxy_pass http://upstream:port/two/; proxy_redirect default; } location /one/ { proxy_pass http://upstream:port/two/; proxy_redirect http://upstream:port/two/ /one/; }
proxy_next_upstream
语法:proxy_next_upstream [error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_404 | off ];
默认:proxy_next_upstream error timeout;
此配置项表示当向一台上游服务器转发请求出现错误时,继续换一台上游服务器处理这个请求。
上游服务器一旦开始发送应答,Nginx反向代理服务器会立刻把应答包转发给客户端。因此,一旦Nginx开始向客户端发送响应包,之后的过程中若出现错误也是不允许换下一台上游服务器继续处理的。这很好理解,这样才可以更好地保证客户端只收到来自一个上游服务器的应答。proxy_next_upstream的参数用来说明在哪些情况下会继续选择下一台上游服务器转发请求。
error:当向上游服务器发起连接、发送请求、读取响应时出错。
timeout:发送请求或读取响应时发生超时。
invalid_header:上游服务器发送的响应是不合法的。
http_500:上游服务器返回的HTTP响应码是500。
http_502:上游服务器返回的HTTP响应码是502。
http_503:上游服务器返回的HTTP响应码是503。
http_504:上游服务器返回的HTTP响应码是504。
http_404:上游服务器返回的HTTP响应码是404。
off:关闭proxy_next_upstream功能—出错就选择另一台上游服务器再次转发。