Nginx和后端应用服务器部署在一起,用户浏览器的HTTP请求经过Nginx,由Nginx转发给后端服务器,这个过程就叫反向代理。
反向代理的用途很多,比如:实现负载均衡,对请求做一些预处理(Cookie处理、权限认证等),动静分离(指页面静态文件和后端应用服务器的动态数据),通过缓存提升响应性能等。
我们这里直接通过几个例子,学习如何使用Nginx实现反向代理。
这里我们在localhost:8080
启动了一个Tomcat,应用服务器的ContextPath为/
,我们需要用Nginx将其代理到localhost:80
,路径改为/app
。
location /app {
proxy_pass http://127.0.0.1:8080/;
}
其中,proxy_pass
就是反向代理的路径。要注意的是,该配置URL最后有一个/
,这代表我们对Nginx/app
发起的请求,会转发到Tomcat的/
路径上,如果配置中没有/
,请求路径/app
就会原样交给Tomcat。
Nginx的反向代理默认使用HTTP1.0协议和被代理的后端进行通信。如果配置反向代理后,访问Nginx返回HTTP 426 Upgrade Required
这个错误,说明后端服务不支持HTTP1.0仅支持HTTP1.1,此时我们需要额外添加一个配置:
location /app {
proxy_pass http://127.0.0.1:8080/;
proxy_http_version 1.1;
}
对于前缀匹配的location
配置,如果用户故意访问/appa
页面,Nginx会向Tomcat请求/a
,假如你还真有这个页面,那就真的会返回给用户/a
的内容,而不是一个404
。此时建议使用其它的匹配方式。
在非前后端分离项目中,比如后端SpringMVC使用的Thymeleaf模板,我们会通过类似<span id="contextPath" style="display: none;">[[@{/}]]</span>
的写法自动获取应用的ContextPath,以供静态资源加载和ajax请求。
如果Nginx中配置的路径和后端路径不一致,这个请求路径对Nginx之前的用户来说,就是错误的路径。如果你发现页面缺少CSS样式,并且ajax都不好使了,那就可能是这个原因。针对这个问题最好是在后端想办法解决(在Nginx上配置URL重写是邪路)。比如将ContextPath变为一个可配置项,线上环境中将其设置为和Nginx中一致,并写在配置文件中,而不是自动根据页面获取。