大家好,今天给各位分享生产环境突发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问题排查指南,以及的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面我们开始吧!
本文采摘于网络,不代表本站立场,转载联系作者并注明出处:https://www.iotsj.com//kuaixun/6470.html
用户评论
发生这种事可真是让人心塞呀!
有6位网友表示赞同!
希望调查快点找出原因,赶紧让网站恢复正常。
有7位网友表示赞同!
服务器崩溃了吗? 可能是网络问题吧?
有18位网友表示赞同!
这可是大事儿啊,影响很多用户体验。
有11位网友表示赞同!
大公司应该有应对这类问题的机制吧?
有16位网友表示赞同!
这种情况下用户肯定很愤怒的。
有6位网友表示赞同!
可怜那些赶上事件的用户吧!
有19位网友表示赞同!
感觉这篇文章作者很有气魄啊,不背锅太酷了~~!
有20位网友表示赞同!
会不会是代码问题引起的?
有11位网友表示赞同!
不知道具体发生了什么事故,希望尽快修好。
有9位网友表示赞同!
大型网站确实要时刻注意防范风险。
有11位网友表示赞同!
这种情况下用户的损失也很可观吧?
有9位网友表示赞同!
生产环境的稳定运行非常重要啊。
有7位网友表示赞同!
读完标题感觉很悬疑,到底是谁在背锅呢?
有11位网友表示赞同!
这篇文章一定很精彩了,想看看作者怎么说!
有7位网友表示赞同!
这种事情听起来就头疼呀!
有15位网友表示赞同!
希望网站方能早日解决问题,给用户一个交代。
有20位网友表示赞同!
网络故障真是让人费劲啊!
有19位网友表示赞同!
这篇文章肯定会有很多留言评论的。
有20位网友表示赞同!
这种事情发生在任何公司身上都是大事!
有6位网友表示赞同!
大数据时代,网站安全问题越来越重要了!
有11位网友表示赞同!