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

 更新时间:2023年09月11日 08:55:40   作者:磊叔的技术博客  
本篇文章原自当前业务遇到的一个实际问题,因为受到所在网络环境的因素影响,所以整体排查下来耗费了很大精力,记录一下Nginx 转发 404 问题的排查和思考,需要的朋友可以参考下

项目背景

项目是 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.2
  • 10.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.25310.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 的日志如下:

"POST /miniapp/user/case HTTP/1.1" 404 153 "-" "Java/1.8.0_351"
"POST /miniapp/user/case HTTP/1.1" 404 153 "-" "Java/1.8.0_351"
"POST /miniapp/user/case HTTP/1.1" 404 153 "-" "Java/1.8.0_351"

因为这个请求不是 10.31.31.253 对应的 10.13.3.177 这台机器上的服务处理,而是直接转发给 10.233.1.2 对应的 172.13.7.249 机器的,因此这里出现 404,因为是转发到 172.13.7.249 时没有找到相应的资源。查看 249 机器上的 nginx 访问日志

"POST /user/case HTTP/1.0" 404 153 "-" "Java/1.8.0_351"
"POST /user/case HTTP/1.0" 404 153 "-" "Java/1.8.0_351"
"POST /user/case HTTP/1.0" 404 153 "-" "Java/1.8.0_351"

可以看到, 249 这台机器上的请求变成了 /user/case,丢失了 /miniapp 这个 prefix,10.13.3.177 机器的 nginx 配置如下:

location /miniapp/ {
    // 主要是这里
    proxy_pass http://10.31.31.253:8805/;
}

关于这个问题,解决方案大致有如下几种(来源各种技术文章):

  • 1、修改代理配置:将匹配以 /miniapp 开头的所有请求,并将它们代理到 10.31.31.253:8805,保持请求 URI 不变。
location /miniapp {
    proxy_pass http://10.31.31.253:8805;
}
  • 2、使用正则表达式捕获和重写 URI:捕获以 /miniapp 开头的请求,并将 /miniapp 后面的部分传递给后端服务器。
location ~ ^/miniapp(/.*)$ {
    proxy_pass http://10.31.31.253$1;
}
  • 3、rewrite 重写:使用 rewrite 指令将 /miniapp 后面的部分提取出来,然后将其传递给后端服务器
location /miniapp/ {
    rewrite ^/miniapp(/.*)$ $1 break;
    proxy_pass http://10.31.31.253;
}
  • 4、保留 location 前缀:就是将 location 前缀保留在 proxy_pass 的后面
location /miniapp/ {
    proxy_pass http://10.31.31.253:8805/miniapp/;
}

经测试,方案 1 和 方案 4 是可以解决 404 问题的。其中方案 4 是**有病治病的逻辑,转发丢弃则就加上。**这两个问题对于了解 nginx proxy_pass 配置的同学来说应该一眼就可以看到问题所在,但是 大多数时候,我们会忽略那些看起来并不是很显眼的东西,比如 /

proxy_pass 配置以 / 结尾和不以 / 结尾的区别

  • 以 / 结尾的proxy_pass配置
location /miniapp/ {
    proxy_pass http://10.31.31.253:8805/;
}

这种配置方式没有斜杠 / 结尾,意味着 Nginx 会将原始请求的 URI 原封不动地传递给后端服务器。例如,如果原始请求是 http://10.31.1.142/miniapp/user/case,那么 Nginx 会将它代理到http://10.31.31.253:8805/miniapp/user/case。

所以说,如果你希望将请求映射到后端服务器的根目录,则可以使用以斜杠 / 结尾的配置。如果你希望保持URI不变,可以使用不以 / 结尾的配置。

关于 proxy_pass 以及 location

网上关于这两个介绍的文章非常多,本篇不做过多的阐述。

  • proxy_pass 指令用于定义 Nginx 的 反向代理 功能。它指定了将客户端请求代理到的后端服务器的地址。
  • location 指令用于匹配客户端请求的 URI,然后定义如何处理这些请求。

问题其实不是很复杂,主要还是对于 nginx 的一些配置作用不大清楚,另外就是在实际排查过程中,因为链路和网络环境问题走了很多弯路;但是如果把这些信息梳理清楚了,就会拨云见日;问题就在那里,复杂的是过程

以上就是Nginx转发404问题的排查和思考的详细内容,更多关于Nginx转发404的资料请关注脚本之家其它相关文章!

相关文章

  • nginx搭建高可用集群的实现方法

    nginx搭建高可用集群的实现方法

    本文主要介绍了nginx搭建高可用集群的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • Nginx多个前端服务配置方式详解

    Nginx多个前端服务配置方式详解

    这篇文章主要介绍了Nginx多个前端服务配置方式,主要包括多个location配置,多个server配置,配置方式本文给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2022-03-03
  • 如何解决Nginx请求转发将POST变为GET问题

    如何解决Nginx请求转发将POST变为GET问题

    这篇文章主要介绍了如何解决Nginx请求转发将POST变为GET问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • Nginx 部署及配置详细步骤(附详细代码)

    Nginx 部署及配置详细步骤(附详细代码)

    Nginx是一个web服务器也可以用来做负载均衡及反向代理使用,目前使用最多的就是负载均衡,这篇文章主要介绍了Nginx部署及配置的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-11-11
  • Nginx配置ssl实现https的全过程记录

    Nginx配置ssl实现https的全过程记录

    这篇文章主要给大家介绍了关于Nginx配置ssl实现https的相关资料,文章通过实例代码介绍的非常详细,对大家学习或者使用Nginx具有一定的参考学习价值,需要的朋友可以参考下
    2022-03-03
  • 详解nginx使用ssl模块配置支持HTTPS访问

    详解nginx使用ssl模块配置支持HTTPS访问

    这篇文章主要介绍了详解nginx使用ssl模块配置支持HTTPS访问,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • Nginx 安装与配置规则入门详解

    Nginx 安装与配置规则入门详解

    这篇文章主要介绍了Nginx 安装与配置规则入门详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-02-02
  • 在Nginx服务器上配置Google反向代理的基本方法

    在Nginx服务器上配置Google反向代理的基本方法

    这篇文章主要介绍了在Nginx服务器上配置Google反向代理的基本方法,文中使用到了SSL来加密反向代理,需要的朋友可以参考下
    2015-12-12
  • Nginx 应用范围和使用详解

    Nginx 应用范围和使用详解

    这篇文章主要介绍了Nginx 应用范围和使用详解的相关资料,需要的朋友可以参考下
    2017-03-03
  • Keepalived+Nginx+Tomcat 实现高可用Web集群的示例代码

    Keepalived+Nginx+Tomcat 实现高可用Web集群的示例代码

    这篇文章主要介绍了Keepalived+Nginx+Tomcat 实现高可用Web集群的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09

最新评论