nginx 通过 location proxy_pass 配置后台接口 API 代理时不清楚 location 、proxy_pass 路径语法时的万能调试办法!

4 篇文章 0 订阅
2 篇文章 0 订阅

假设 nginx.conf 中有如下配置:

server {
    listen       8080;
    server_name  127.0.0.1;
    ...

    # 请求后台接口的 api配置
    location ^~ /userapi {
        proxy_pass   http://127.0.0.2:8081;
    }
}

后台的一个接口的请求路径实际为:http://127.0.0.2:8081/userCenter/queryUserInfo,其中 /userCenter为后台接口服务工程的 server.servlet.context-path,

现在需要达到的效果就是浏览器输入 http://127.0.0.1:8080/userapi/queryUserInfo ,实际上需要 nginx 请求到 http://127.0.0.2/userCenter/queryUserInfo 接口,

但是现在对 nginx 的 location 的路径语法不熟悉,对 location --》proxy_pass 路径语法也不熟悉,不知道 userapi 前、后是否要带 " " 和 "/",不知道 http://127.0.0.2:8081 后面是否要带 "/" ( 还是带 /userCenter ),一个绝对正确的做法就是尝试全部的排列组合,location 的写法的全部可能性如下所示:

1. location ^~ /userapi{...
2. location ^~ /userapi {...
3. location ^~ /userapi/{...
4. location ^~ /userapi/ {...
5. location ^~ userapi{...
6. location ^~ userapi {...
7. location ^~ userapi/{...
8. location ^~ userapi/ {...
9. location ^~/userapi{...
10. location ^~/userapi {...
11. location ^~/userapi/{...
12. location ^~/userapi/ {...
13. location ^~userapi{...
14. location ^~userapi {...
15. location ^~userapi/{...
16. location ^~userapi/ {...

一共 16 种,

proxy_pass 的全部可能性如下所示:

1. http://127.0.0.2:8081;
2. http://127.0.0.2:8081/;
3. http://127.0.0.2:8081/userCenter;
4. http://127.0.0.2:8081/userCenter/;

一共 4 种,所以一共有 16 X 4 = 64 种可能性,像无头苍蝇一样试来试去,太费事费力,不可取。

如果可以将 nignx 最终拼成的向后台服务发出请求的完整 url 输出出来,则对我们定位是前缀拼错了还是后缀拼错了,或者多拼了什么还是少拼了什么有很大帮助....

方法是有的,可以查看 nginx 安装目录下的 access.log 和 error.log,例如:.../nginx-1.24.0/logs 下的 access.log、error.log,如果不想用此方法,或者nginx 加了什么配置导致不会输出,其实可以用第二种方案,在后台接口工程 userCenter  中加一个过滤器或者拦截器,比如拦截器如下所示:

 @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request1 = (HttpServletRequest) request;
        String url = request1.getRequestURL().toString();
        System.out.println( "url = " + url );
        chain.doFilter(request, response);
    }

这样所有的请求最终都会输出其完整的 url ,但是要记得将该工程的 server.servlet.context-path

临时修改为 "/",目的是使得即使 location 和 proxy_pass 的路径语法写错了,nginx 实际转发出去的地址也能被打到后台工程中,只是找不到对应的接口罢了(  当然 proxy_pass 必须以 "http://127.0.0.2:8081" 开头,你要是端口都写错了,那肯定不行 )。

以下是 2 种错误写法:

错误写法1:

发出请求:http://127.0.0.1:8080/userapi/queryUserInfo
location ^~ /userapi/ {
    proxy_pass   http://127.0.0.2:8081/;
}
实际的转发路径:http://127.0.0.2:8081/queryUserInfo

错误写法2:

发出请求:http://127.0.0.1:8080/userapi/queryUserInfo
location ^~ /userapi {
    proxy_pass   http://127.0.0.2:8081/;
}
实际的转发路径:http://127.0.0.2:8081//queryUserInfo
所以我们有理由相信 nginx 是将 proxy_pass 和 浏览器发出的 url 中去掉 location 中的部分后剩下的后缀部分 拼接在一起作为实际转发出去的 url,即 实际转发出去的 url = ${proxy_pass} + ${浏览器发出的地址}.replaceAll( ${location},"" )。这也就解释了为啥 "错误写法2" 中实际转发的路径中会有 "//" 了。

然后我们再测试2种正确写法和1种错误写法来更加应证明我们的猜想:

2种正确写法:

发出请求:http://127.0.0.1:8080/userapi/queryUserInfo
location ^~ /userapi/ {
    proxy_pass   http://127.0.0.2:8081/userCenter/;
}   
实际转发出去的 url:http://127.0.0.2:8081/userCenter/queryUserInfo


发出请求:http://127.0.0.1:8080/userapi/queryUserInfo
location ^~ /userapi {
    proxy_pass   http://127.0.0.2:8081/userCenter;
}
实际转发出去的 url:http://127.0.0.2:8081/userCenter/queryUserInfo

1种错误写法:

发出请求:http://127.0.0.1:8080/userapi/queryUserInfo
location ^~ /userapi/ {
    proxy_pass   http://127.0.0.2:8081/userCenter;
}
实际转发出去的 url:http://127.0.0.2:8081/userCenterqueryUserInfo

最后记得还原后端工程的 server.servlet.context-path

结语:俗话说授人以鱼不如授人以渔,我们的脑子不应该装具体的正确的语法,应该装可以帮助我们快速找到正确的语法的方法,因为语法也是人写的嘛,是会变的,我不知道我也不care,只要知道解决问题的思路就行

ps:前端 vue、react 等脚手架工程本地启动设置后台接口代理如果配置不正确也可以使用此方法快速定位路径语法问题

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值