前提应知:
先说一下ContextPath:称为web应用的上下文路径,简单理解为web容器最开始路径,所有的web资源(路径)都要挂在它的下面,使用request.getContextPath()
可获得,SpringBoot中的配置为server.servlet.context-path
,ContextPath的值只能为以下两种形式:
- 空字符串:即长度为0的字符串
- /xxx:形如“/xxx”形式的字符串,可以是 /xxx、/xxx/yyy、/xx x/yyy,但 /xxx/在SpringBoot中最终会被处理成/xxx
在nginx反向代理的location中,我们都知道location的匹配格式(写法)决定了不同的匹配方式,从而影响最终的代理到的url。通用匹配是最常用的写法,比如为了方便管理,需要做一套应用的代理。一套应用意思就是几个项目互相依赖组成一个可用的应用,如分布式架构、sso等。这个时候我们需要将这些应用都挂到一个nginx(nginx服务器)的端口下,这样对用户来说好像就一直在访问一个应用。对外提供接口也比较方便,因为用的都是同一个端口。
在通用匹配中location和proxy_pass指令的写法还是有必要注意一下ContextPath的值的,避免掉坑。
都知道通用匹配形如
1 | location /xxx { |
此时若该location块所在的server块监听的端口为8000,那么上述写法可以这样理解:一个代理挂在了8000端口下的,名为 /xxx;因为假如现在需要在此时可以再加个location去代理其它的地址,端口依旧可以用8000,。
若location如下,
1 | location / { |
则可以这样理解:一个代理独占了8000端口;再加一个location去代理其它地址就不太好操作,搞不好容易出现代理错误的情况。
下面以上述两种location写法做个测试。
通用匹配测试
nginx服务器:
IP:192.168.100.100
SpringBoot应用:
IP:192.168.0.200;
一个控制层方法:
1 |
|
配置文件aplication.properties:
1 | # web容器上下文路径,不写则默认为空字符串 |
测试结果:
context-path | location | proxy_pass | 结果 | 描述 |
---|---|---|---|---|
- | / | 192.168.0.200:8080 | ok | |
- | / | 192.168.0.200:8080/ | ok | |
- | /app | 192.168.0.200:8080 | 404 | nginx最终代理到:192.168.0.200:8080/app/test |
- | /app | 192.168.0.200:8080/ | ok | |
/demo | / | 192.168.0.200:8080/demo | 404 | nginx最终代理到:192.168.0.200:8080/demotest |
/demo | / | 192.168.0.200:8080/demo/ | ok | |
/demo | /app | 192.168.0.200:8080/demo | ok | |
/demo | /app | 192.168.0.200:8080/demo/ | ok |
可见,location的写法和要代理到的目标地址还是有讲究的,详细的话就不说了,为了防止出错,简单一句话总结:
proxy_pass = ip + port + ContextPath,要到的目标应用ContextPath为空字符串时,location写“/”,反之写ContextPath;
有域名的情况自行适配即可。