Nginx 故障排查之斜杠(/) --(附 Nginx 常用命令)

news/2024/7/7 21:44:06 标签: nginx, 运维

问题场景:

项目中用到了多个子域名,测试环境通过子域名进行接口访问的时候返回 404 NOT_FOUND,经过排查测试后确定是 Nginx 配置问题,而导致事故的根本原因是运维在Nginx配置的时候少配置了一个斜杠(/),下面我们来聊聊具体情况。

故障现象如下:

nginx 配置如下:

 location /api/{
       client_max_body_size 100m;
       proxy_connect_timeout 120;
       proxy_send_timeout 120;
       proxy_read_timeout 120;
       proxy_set_header Host $http_host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header REMOTE-HOST $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_pass http://10.xxx.xxx.xxx:8080/api;
    }

接口请求结果如下:

在这里插入图片描述

{
    "code": 404,
    "message": "404 NOT_FOUND",
    "data": ""
}

问题分析:

  • 接口不存在,直接通过服务部署的机器,通过 ip + 端口访问,正常响应。
  • 网关 Gateway 有问题,通过 Gateway 服务部署的机器,通过 ip + 端口访问,正常响应。
  • Nginx 配置有问题,通过 Nginx 的机器IP和暴露的端口去访问,响应 404,基本可以确定Nginx 配置有问题

原因分析:

  • 通过对问题现象分析,我们基本确定是 Nginx 配置的问题,我们取查询 Nginx 的日 看是否可以找到有效信息,没有找到有用信息。
  • 接着我们对 Gateway 日志进行分析,看看是否可以找到有用的信息,我们发现了这样一段日志, /apidxx/v1/szzz/method(真实接口路径不方便暴露,请理解),apidxx 这段有明显问题,api 后面应该有个斜杆 / ,才接着是 dxx 才对,这段日志是在 Gateway 发现的,再次证明是 Nginx 配置的问题,现在我们进一步确定了是少了个斜杠 /,已经确定到了问题,现在去排查 Nginx 配置即可。

分析 Nginx 配置:

我们发现 proxy_pass http://10.xxx.xxx.xxx:8080/api 这段配置在api 后面没有接斜杠 / ,对比我们上面的分析,果断加上斜杠试试,重启后问题解决,正确的 Nginx 配置如下:

location /api/{
      client_max_body_size 100m;
      proxy_connect_timeout 120;
      proxy_send_timeout 120;
      proxy_read_timeout 120;
      proxy_set_header Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header REMOTE-HOST $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://10.xxx.xxx.xxx:8080/api/;
   }

问题解决了,下面我们来分析一下,斜杠的各种场景。

location、proxy_pass 斜杠分析:

以下分析,不在赘述验证流程,感兴趣的朋友可以自己去验证,也欢迎提出疑问。
虚拟场景:我们需要通过 Nginx 代理访问地址:http://127.0.0.1/api/zt/app/list。

location加斜杠,proxy_pass 加api(上面分析的案例),如下:

location /api/ {
    proxy_pass http://127.0.0.1:8888/api;
}

实际访问地址 :http://127.0.0.1:8888/apizt/app/list,这是个错误的地址,apizt 之间少了斜杠 /,导致 404。

location 不加斜杠,proxy_pass 加 api,api后面不加斜杠 /,如下:

location /api {
    proxy_pass http://127.0.0.1:8888/api;
}

实际访问地址 :http://127.0.0.1:8888/api/zt/app/list,地址正确。

location 不加斜杠,proxy_pass 加 api,api后面加斜杠 /,如下:

location /api {
    proxy_pass http://127.0.0.1:8888/api/;
}

实际访问地址 :http://127.0.0.1:8888/api/zt/app/list,地址正确。

location 加斜杠,proxy_pass 加 api,api后面加斜杠 /,如下:

location /api/ {
    proxy_pass http://127.0.0.1:8888/api/;
}

实际访问地址 :http://127.0.0.1:8888/api/zt/app/list,地址正确。

location 不加斜杠,proxy_pass 不加 api,如下:

location /api {
    proxy_pass http://127.0.0.1:8888;
}

实际访问地址 :http://127.0.0.1:8888/api/zt/app/list,地址正确。

location 加斜杠,proxy_pass 不加 api,如下:

location /api/ {
    proxy_pass http://127.0.0.1:8888;
}

实际访问地址 :http://127.0.0.1:8888/api/zt/app/list,地址正确。

location 加斜杠,proxy_pass 不加 api,如下:

location /api {
    proxy_pass http://127.0.0.1:8888/;
}

实际访问地址 :http://127.0.0.1:8888//api/zt/app/list,地址错误

总结:

我们发现 proxy_pass 基本可以分为两种配置方法,一种是代理地址端口无字符,另外一种则是代理地址端口后有字符,下面给出结论:

  • proxy_pass 代理地址端口后无任何字符,转发后实际地址:代理地址+访问URL接口路径部分。
  • proxy_pass 代理地址端口后有目录(包括 / ),转发后实际地址:代理地址+访问URL目录部分去除location匹配目录。

Nginx常用命令:

#查看Nginx 进程命令
ps aux|grep nginx
#优雅停止Nginx服务器命令
/data/svr/nginx/sbin/nginx -s quit
#启动Nginx服务器命令(Nginx 很多命令都是在 sbin 目录下执行)
#去到sbin路径:cd /usr/local/nginx/sbin
#启动Nginx服务器: ./nginx
#修改配置后检查配置文件是否出错
/data/svr/nginx/sbin/nginx -t
#修改配置后热加载
/data/svr/nginx/sbin/nginx -s reload
#指定启动配置文件命令
/data/svr/nginx/sbin/nginx -c /data/svr/nginx/conf/nginx.conf
#暴力停止Nginx服务器命令
/data/svr/nginx/sbin/nginx -s stop
#优雅停止Nginx服务器命令
/data/svr/nginx/sbin/nginx -s quit

如有不正确的地方欢迎各位指出纠正。


http://www.niftyadmin.cn/n/5451691.html

相关文章

使用aop做权限控制

1、pom.xml文件内容如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http:/…

【SpringBoot】实现一个简单的图片上传

前端上传表单 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body> <form enctype"multipart/form-data" method"post" action&q…

蓝桥杯嵌入式第13届第一场——密码锁

做题步骤 1.LCD显示 按要求将背景色和字体色更改 切换界面变量&#xff0c;当密码正确时切换界面 键盘值和密码&#xff0c;当键盘值 密码则输入密码正确 当处于密码输入界面时LCD在密码输入界面显示以下内容 当密码输入正确时LCD进入数据显示模式显示以下内容 2.按键显示 …

Git基础(24):分支回退

文章目录 前言放弃已修改的内容分支回退到指定commit 前言 将分支回退到之前的某个版本 开发中&#xff0c;可能开发某个功能不需要了&#xff0c;或者想要回退到之前历史的某个commit&#xff0c; 放弃后来修改的内容。 放弃已修改的内容 如果未提交&#xff0c;直接使用 …

C语言学习--字符串和整型的转换

目录 整型→字符串 方法1&#xff1a;利用‘0’将单个数字转字符 方法2&#xff1a;利用sprintf函数 方法3&#xff1a;利用itoa函数 字符串→整型 方法1&#xff1a;利用-‘0’直接转换 方法2&#xff1a;利用atoi函数 整型→字符串 整形数据变成字符串&#xff0c;最…

Android 15兼容性框架变更

在准备支持 Android 15 和以该平台为目标平台时&#xff0c;请将此列表与开发者选项和 ADB 命令结合使用&#xff0c;以测试和调试您的应用。 以下是您可以使用兼容性框架工具进行的操作&#xff1a; 在不实际更改应用的 targetSdkVersion 的情况下测试针对性的变更。您可以使…

rust中字符串String常用方法和注意事项

Rust 中通常说的字符串指的是&#xff1a;String 和 &str(字符串字面值、或者叫字符串切片)这两种类型。str是rust中基础字符串类型&#xff0c;String是标准库里面的类型。Rust 中的字符串本质上是&#xff1a;Byte的集合&#xff08;Vec<u8>&#xff09; 基础类型…

ajax、fetch、axios它们之间的差异与区别是什么?为什么我们的项目中建议使用axios?

ajax 的优缺点: 属js原生&#xff0c;基于XHR进行开发&#xff0c;XHR结构不清晰 针对 mvc 编程&#xff0c;由于近来vue和React的兴起&#xff0c;不符合mvvm前端开发流程 单纯使用ajax 封装&#xff0c;核心是使用 XMLHttpRequest 对象,使用较多并有先后顺序的话&#xff0c;…