1. 首页 > 快讯

生产环境突发404问题排查指南

大家好,今天给各位分享生产环境突发404问题排查指南的一些知识,其中也会对进行解释,文章篇幅可能偏长,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在就马上开始吧!

今天,我到公司迟到了。肯定是因为我的一个朋友昨晚下班了,在离开办公室之前没有祈祷服务器不要出现任何问题。我们要把这个人找出来,挂在服务器上祭天!

问题复现

得知操作反馈后,我迅速登录服务器排查问题。首先检查接口服务启动过程是否正常。验证接口服务的IP和端口是否正常,没有问题。接下来,请求通过Nginx转发。这时候就出现问题,无法访问接口。同时Nginx的access.log文件中输出如下日志信息。

192.168.175.120 - - [2024-08-03 21:34:21 +0800] 'GET /third/system/base/thirdapp/get_detail HTTP/1.1' 404 0 'http://192.168.175.100/api/index.html' 'Mozilla/5.0 (Windows NT 10.0; Win64 0 'http://192.168.175.100/api/index.html' 'Mozilla/5.0 (Windows NT 10.0; Win64; 36034:26 +0800] 'GET /third/system/base/thirdapp/get_detail HTTP/1.1' 404 0 'http://192.168.175.100/api/index.html' 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0' 此时从Nginx日志中发现输出status为404,未找到后端接口服务为了进一步定位问题,我在线上环境下直接通过curl命令访问接口服务,结果正常。

经过这一系列的操作,我们可以确定问题出在Nginx上。

问题分析

Nginx开启debug模块

既然问题已经定位,那么我们就要分析一下问题的具体原因。既然是Nginx的问题,我首先想到的就是调试Nginx,找出错误原因。于是我在服务器命令行输入如下命令来检查安装Nginx时的配置。

nginx -V 注意:这里已经为Nginx配置了系统环境变量。如果没有配置系统环境变量,则需要输入nginx命令所在目录的完整路径,例如:

/usr/local/nginx/sbin/nginx -v 命令行输出以下信息。

配置arguments: --prefix=/usr/local/nginx --with-http_stub_status_module --add-module=/usr/local/src/fastdfs/fastdfs-nginx-module-1.22/src --with-openssl=/usr/local/src/openssl-1.0.2s --with-pcre=/usr/local/src/pcre-8.43 --with-zlib=/usr/local/src/zlib-1.2.11 --with-http_ssl_module 可以查看是的,安装Nginx时没有配置Nginx的debug模块。

于是我在服务器上找到了Nginx的安装文件,并在命令行输入以下命令重新编译Nginx。

cd /usr/local/src/nginx/#进入Nginx安装文件根目录make clean #清除编译信息/configuration --prefix=/usr/local/nginx-1.17.8 --with-http_stub_status_module - -add- module=/usr/local/src/fastdfs/fastdfs-nginx-module-1.22/src --with-openssl=/usr/local/src/openssl-1.0.2s --with-pcre=/usr/local/src /pcre-8.43 --with-zlib=/usr/local/src/zlib-1.2.11 --with-http_ssl_module --with-debug #设置编译Nginx的配置信息make #编译Nginx,切记不要如上输入make install 命令中,切记不要输入make install 进行安装。

执行make命令后,会在当前目录的objs目录下生成nginx命令。这时我们需要先停止Nginx服务,备份/usr/local/nginx/sbin/目录下的nginx命令,然后复制objs目录下的nginx命令。将命令复制到/usr/local/nginx/sbin/目录下,然后启动Nginx服务。

nginx_service.sh stop #通过脚本停止Nginx服务mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak #备份原来的nginx命令cp ./objs/nginx /usr /local/nginx/sbin/nginx #复制nginx命令nginx_service.sh start #通过脚本启动Nginx服务注意:这里,在停止Nginx服务之前,Nginx已经从接入层网关中移除,所以不会影响线上环境。为了避免使用新编译的nginx命令重新启动Nginx时出现问题,我们先通过脚本停止Nginx服务,然后复制nginx命令,然后启动Nginx服务。

配置Nginx输出debug日志

在Nginx的nginx.conf文件中配置以下信息。

error_log 日志/error.log 调试;此时Nginx的调试日志功能开启,调试信息输出到error.log文件中。

分析问题

接下来,在服务器命令行输入以下命令来监控error.log文件的输出日志。

tail -F /usr/local/nginx/logs/error.log 然后模拟访问http接口。可以在error.log文件中看到以下信息输出。

2024-08-03 21:34:26 [调试] 31486#0: *56 http请求行: 'GET /third/system/base/thirdapp/get_detail HTTP/1.1'2024-08-03 21:34:26 [调试] 31486#0: * 56 http uri: ' /third/system/base/thirdapp/get_detail'2024-08-03 21:34:26 [调试] 31486#0: *56 http args: ''2024-08-03 21:34:26 [调试] 31486#0: *56 http 前十: ''2024- 08 -03 21:34:26 [调试] 31486#0: *56 posix_memalign: 0000000000FF6450:4096 @162024-08-03 21:34:26 [调试] 31486#03 336 0 *56 http处理请求头行2024-08-03 21:34:26 [调试] 31486#0: *56 http header: 'Host: 10.31.5.66'2024-08-03 21:34:26 [调试] 31486#0: *56 http header: 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Geck o/20100 101 火狐/85.0' 2024-08-03 21:34:26 [调试] 31486#0: *56 http header: 'Accept-Language33 360 zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US ;q=0.3,en;q=0.2'2024-08-03 21:34:26 [调试] 31486#0: *56 http header: 'Accept-Encoding: gzip , deflate'2024-08-03 21:34:26 [调试] 31 486#0: *56 http header: 'Referer: http://192.168.175.100/api/index.html'2024-08-03 21:34:2 6 [调试] 31486#0: *56 http header: 'Connection: keep -alive'2024-08-03 21:34:26 [调试] 31486#0: *56 http标头done2024-08-03 21:34:26 [调试] 31486#0: *56重写阶段: 02024-08-03 2 1:34:26 [调试] 31486#0: *56测试位置: '/'2024 -08-03 21:34:26 [调试] 31486#0: *56 测试位置: 'file/'2024-08-03 21:34:26 [调试] 31486#0: *56 测试位置: ~ ' /base'2024-08-03 21:34:26 [调试] 31486#0: *56 使用配置'/base'来自上面的输出日志,我们可以看到访问的接口地址为“/third/system/base/thirdapp/get_detail”,如下所示。

2024-08-03 21:34:26 [debug] 31486#0: *56 http uri: '/third/system/base/thirdapp/get_detail' Nginx转发时匹配了“/”、“file/”、“~/base”” ,最后将请求转发到“/base”,如下图。

2024-08-03 21:34:26 [调试] 31486#0: *56 测试位置: '/'2024-08-03 21:34:26 [调试] 31486#0: *56 测试位置: '文件/'2024- 08 -03 21:34:26 [调试] 31486# 0: *56 test location: ~ '/base'2024-08-03 21:34:26 [debug] 31486#0: *56 using configuration '/base' 我们再看一下Nginx的配置,打开nginx.conf文件,找到以下配置。

位置~/base { proxy_pass http://base; proxy_set_header 主机$host:$server_port;} 位置~/third { proxy_pass http://third; proxy_set_header Host $host:$server_port;} 那么问题来了,访问接口明明是“/third/system/base/thirdapp/get_detail”,为什么会走到“/base”下面呢?

至此,相信细心的朋友已经发现问题了。是的,又是运维的错!

解决问题

看完Nginx的配置,相信很多朋友应该知道如何解决问题了。是的,就是nginx.conf 中的以下配置。

位置~/base { proxy_pass http://base; proxy_set_header 主机$host:$server_port;} 位置~/third { proxy_pass http://third; proxy_set_header 主机$host:$server_port;} 修改如下。

位置/基地{ proxy_pass http://base; proxy_set_header 主机$host:$server_port;} 位置/third { proxy_pass http://third; proxy_set_header Host $host:$server_port;} 只需删除“~”符号即可。

接下来再次模拟访问http接口,就可以正常访问接口了。

接下来,关闭Nginx的debug功能,即注释掉error_log日志/error.log debug;配置在nginx.conf文件中,如下所示。

# error_log 日志/error.log 调试;重新加载nginx.conf 文件。

nginx_service.sh reload 最后将Nginx添加到接入层网关,问题解决。

科普Nginx的转发规则

Nginx的location语法

位置[=|~|~*|^~] /uri/{ … }=严格匹配。如果请求匹配到该位置,则停止搜索,立即处理请求~区分大小写匹配(可用正则表达式)~* 不区分大小写匹配(可用正则表达式)!~区分大小写不匹配!~*不区分大小写的不匹配^~如果这个前缀与正则字符串一起使用,它告诉nginx如果路径匹配则不要测试正则表达式。示例1:

location/{} 匹配任何请求

示例2:

location ~* .(gif|jpg|jpeg)$ {rewrite .(gif|jpg|jpeg)$ /logo.png;} 匹配任何以gif、jpg、jpeg 结尾的请求,不区分大小写,并重写请求定向的请求到/logo.png

示例3:

location ~ ^.+\.txt$ { root /usr/local/nginx/html/;} 区分大小写匹配以.txt 结尾的请求,并将该位置的路径设置为/usr/local/nginx/html/。即以.txt结尾的请求将访问/usr/local/nginx/html/路径下的txt文件

alias与root的区别

root 实际访问的文件路径会与URL中的路径拼接。 alias 实际访问的文件路径,不会与URL中的路径拼接。示例如下:

位置^~ /binghe/{ 别名/usr/local/nginx/html/binghetic/;请求:http://test.com/binghe/binghe1.html 实际访问:/usr/local/nginx/html/binghetic/binghe1.html 文件位置^~ /binghe/{ root /usr/local/nginx/html/;请求:http://test.com/binghe/binghe1.html 实际访问:/usr/local/nginx/html/binghe/binghe1.html 文件

last 和 break关键字的区别

(1)当last和break出现在location之外时,效果相同任何差异。

(2)last和break出现在位置内部时:

最后使用最后一条指令。重写后会跳出位置范围。重新开始并重复刚才的行为。中断使用中断指令。重写后,不会跳出位置范围。它的整个生命周期都在当前位置。

permanent 和 redirect关键字的区别

rewrite.permanent 永久重定向,请求日志中的状态码为301 rewrite.redirect 临时重定向,请求日志中的状态码为302

综合实例

将匹配某个正则表达式的URL 重定向到固定页面

例如:我们需要将匹配正则表达式“/test/(\d+)/[\w-.]+”的URL重定向到固定页面。匹配该正则表达式的页面可能有:http://test.com/test/12345/abc122.html、http://test.com/test/456/11111cccc.js等。

从上面的介绍可以看出,我们可以使用rewrite重定向或者alias关键字来达到我们的目的。所以你可以这样做:

(1)使用rewrite关键字

位置~ ^.+\.txt$ { root /usr/local/nginx/html/;}位置~* ^/test/(\d+)/[\w-\.]+$ { 重写^/test/( \d+)/[\w-\.]+$ /testpage.txt last;}这里,所有符合条件的URL(PS:不区分大小写)都被重定向到/testpage.txt请求,即/usr/local/nginx /html/testpage.txt 文件

(2)使用alias关键字

location ~* ^/test/(\d+)/[\w-\.]+$ { alias /usr/local/nginx/html/binghetic/binghe1.html;}这里将是所有符合条件的URL(不区分大小写) ) 被重定向到/usr/local/nginx/html/binghetic/binghe1.html 文件

各位老铁们,大家好,今天由我来为大家分享生产环境突发404问题排查指南,以及的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面我们开始吧!

用户评论

挽手余生ら

发生这种事可真是让人心塞呀!

    有6位网友表示赞同!

聽風

希望调查快点找出原因,赶紧让网站恢复正常。

    有7位网友表示赞同!

断秋风

服务器崩溃了吗? 可能是网络问题吧?

    有18位网友表示赞同!

经典的对白

这可是大事儿啊,影响很多用户体验。

    有11位网友表示赞同!

水波映月

大公司应该有应对这类问题的机制吧?

    有16位网友表示赞同!

雨后彩虹

这种情况下用户肯定很愤怒的。

    有6位网友表示赞同!

暖瞳

可怜那些赶上事件的用户吧!

    有19位网友表示赞同!

罪歌

感觉这篇文章作者很有气魄啊,不背锅太酷了~~!

    有20位网友表示赞同!

见朕骑妓的时刻

会不会是代码问题引起的?

    有11位网友表示赞同!

单身i

不知道具体发生了什么事故,希望尽快修好。

    有9位网友表示赞同!

刺心爱人i

大型网站确实要时刻注意防范风险。

    有11位网友表示赞同!

花开丶若相惜

这种情况下用户的损失也很可观吧?

    有9位网友表示赞同!

孤廖

生产环境的稳定运行非常重要啊。

    有7位网友表示赞同!

浮光浅夏ζ

读完标题感觉很悬疑,到底是谁在背锅呢?

    有11位网友表示赞同!

巴黎盛开的樱花

这篇文章一定很精彩了,想看看作者怎么说!

    有7位网友表示赞同!

短发

这种事情听起来就头疼呀!

    有15位网友表示赞同!

棃海

希望网站方能早日解决问题,给用户一个交代。

    有20位网友表示赞同!

反正是我

网络故障真是让人费劲啊!

    有19位网友表示赞同!

笑傲苍穹

这篇文章肯定会有很多留言评论的。

    有20位网友表示赞同!

有阳光还感觉冷

这种事情发生在任何公司身上都是大事!

    有6位网友表示赞同!

歇火

大数据时代,网站安全问题越来越重要了!

    有11位网友表示赞同!

本文采摘于网络,不代表本站立场,转载联系作者并注明出处:https://www.iotsj.com//kuaixun/6470.html

联系我们

在线咨询:点击这里给我发消息

微信号:666666