HPB中文网
HPB中文网
你的位置:HPB中文网 > GROKCEO中文网 > Nginx转发404问题的排查和思考

Nginx转发404问题的排查和思考

发布日期:2025-01-04 11:11    点击次数:156
项目背景 项目是 toG 项目,部署的网络环境是一个大的内网环境(又具体分为内网和内网互联网区),项目涉及到小程序、前端、后端(又包括 JAVA 和 GO 两个项目)的部署。整体的部署拓扑图大致如下: 虚拟 IP 映射:大多数内网如何需要暴露对外访问,会在出口的核心路由上配置一个虚拟的 IP 作为对外的统一访问入口。比如你的内网地址及端口是 10.13.3.177:8080,则通过虚拟 IP 映射的地址及端口可能是:10.31.31.253:8080。 在这个业务流程程,访问路径是:公网(小程序前台)-> 内网互联网区【10.31.1.142(nginx + 小程序后台)】 -> 【10.31.31.253 -> 10.13.3.177(nginx+后端)】 -> 【10.233.1.2 -> 172.13.7.249(nginx+后端)】。其中 10.13.3.177 和 172.13.7.249 是两台虚拟机,虚拟机上部署了nginx 和 后端服务。 PS:上述所有的 IP 均已做过处理,非正式 IP。 问题 访问步骤及问题节点: 1、小程序访小程序后台服务2、小程序后台服务发起调用到 10.31.31.253(这里实际上是 10.31.1.142 要调用 10.233.1.2 的服务,因为 10.31.1.142 不能直接访问 10.233.1.2,所以借用 10.31.31.253 来实现一层转发逻辑)。 这里会涉及到两个转发, 10.31.31.253 对应的 10.13.3.177 这台机器上的 nginx 需要将 10.31.1.142 的请求转发给 10.233.1.210.233.1.2 对应的 nginx 需要将请求到当前机器的后台服务上 在转发时通过 10.31.31.253 调用 10.233.1.2 时出现 404,10.233.1.2 调用本机后端服务时也出现 404;还有一个 502 是 10.31.1.142 访问 10.31.31.253 出现的。下面是分析问题的大体过程和解决办法。 因端口映射导致的访问 502 问题 前面提到 10.31.31.253 和 10.233.1.2 均是 虚拟 IP ,10.31.31.253:8805 端口映射到虚拟机 10.13.3.177 上的端口是 18805,10.13.3.177 上 nginx 配置的监听端口是 18805,所以 10.31.1.142 在访问的第一跳是 10.31.31.253:8805,但在实际排查中发现, 10.31.1.142 访问的是 10.31.31.253:18805,所以出现 502 问题。 状态码 502 表示 HTTP 协议中的 "Bad Gateway",通常用于表示服务器作为网关或代理时遇到了问题。这个错误通常会在一个服务器作为中介时,无法从另一个服务器获取有效响应以满足客户端请求时出现。 proxy_pass 转发 url 丢弃路径导致的 404 问题 根据前面的背景,实际上两个 404 问题均是因为这个原因导致。10.31.1.142 发起的请求是 10.31.31.253:8805/miniapp/user/case, nginx access.log 的日志如下: 因为这个请求不是 10.31.31.253 对应的 10.13.3.177 这台机器上的服务处理,而是直接转发给 10.233.1.2 对应的 172.13.7.249 机器的,因此这里出现 404,因为是转发到 172.13.7.249 时没有找到相应的资源。查看 249 机器上的 nginx 访问日志 可以看到, 249 这台机器上的请求变成了 /user/case,丢失了 /miniapp 这个 prefix,10.13.3.177 机器的 nginx 配置如下: 关于这个问题,解决方案大致有如下几种(来源各种技术文章): 1、修改代理配置:将匹配以 /miniapp 开头的所有请求,并将它们代理到 10.31.31.253:8805,保持请求 URI 不变。 2、使用正则表达式捕获和重写 URI:捕获以 /miniapp 开头的请求,并将 /miniapp 后面的部分传递给后端服务器。 3、rewrite 重写:使用 rewrite 指令将 /miniapp 后面的部分提取出来,然后将其传递给后端服务器 4、保留 location 前缀:就是将 location 前缀保留在 proxy_pass 的后面 经测试,方案 1 和 方案 4 是可以解决 404 问题的。其中方案 4 是**有病治病的逻辑,转发丢弃则就加上。**这两个问题对于了解 nginx proxy_pass 配置的同学来说应该一眼就可以看到问题所在,但是 大多数时候,我们会忽略那些看起来并不是很显眼的东西,比如 /。 proxy_pass 配置以 / 结尾和不以 / 结尾的区别 以 / 结尾的proxy_pass配置 这种配置方式没有斜杠 / 结尾,意味着 Nginx 会将原始请求的 URI 原封不动地传递给后端服务器。例如,如果原始请求是 ,那么 Nginx 会将它代理到:8805/miniapp/user/case。 所以说,如果你希望将请求映射到后端服务器的根目录,则可以使用以斜杠 / 结尾的配置。如果你希望保持URI不变,可以使用不以 / 结尾的配置。 关于 proxy_pass 以及 location 网上关于这两个介绍的文章非常多,本篇不做过多的阐述。 proxy_pass 指令用于定义 Nginx 的 反向代理 功能。它指定了将客户端请求代理到的后端服务器的地址。location 指令用于匹配客户端请求的 URI,然后定义如何处理这些请求。 问题其实不是很复杂,主要还是对于 nginx 的一些配置作用不大清楚,另外就是在实际排查过程中,因为链路和网络环境问题走了很多弯路;但是如果把这些信息梳理清楚了,就会拨云见日;问题就在那里,复杂的是过程。 以上就是Nginx转发404问题的排查和思考的详细内容,更多关于Nginx转发404的资料请关注脚本之家其它相关文章!