记一次生产环境大面积404问题! (2)

从上面的输出日志中,我们可以看到:访问的接口地址为“/third/system/base/thirdapp/get_detail”,如下所示。

2021/02/26 21:34:26 [debug] 31486#0: *56 http uri: "/third/system/base/thirdapp/get_detail"

Nginx在进行转发时,分别匹配了“/”,“file/”,“~/base”,最终将请求转发到了“/base”,如下所示。

2021/02/26 21:34:26 [debug] 31486#0: *56 test location: "http://www.likecs.com/" 2021/02/26 21:34:26 [debug] 31486#0: *56 test location: "file/" 2021/02/26 21:34:26 [debug] 31486#0: *56 test location: ~ "/base" 2021/02/26 21:34:26 [debug] 31486#0: *56 using configuration "/base"

我们再来看看Nginx的配置,打开nginx.conf文件,找到下面的配置。

location ~/base { proxy_pass ; proxy_set_header Host $host:$server_port; } location ~/third { proxy_pass ; proxy_set_header Host $host:$server_port; }

那么问题来了,访问的接口明明是“/third/system/base/thirdapp/get_detail”,为啥会走到“/base”下面呢?

说到这里,相信细心的小伙伴已经发现问题了,没错,又是运维的锅!!

解决问题

看了Nginx的配置后,相信很多小伙伴应该都知道如何解决问题了,没错那就是把nginx.conf中的如下配置。

location ~/base { proxy_pass ; proxy_set_header Host $host:$server_port; } location ~/third { proxy_pass ; proxy_set_header Host $host:$server_port; }

修改为如下所示。

location /base { proxy_pass ; proxy_set_header Host $host:$server_port; } location /third { proxy_pass ; proxy_set_header Host $host:$server_port; }

去掉“~”符号即可。

接下来,再次模拟访问http接口,能够正常访问接口。

接下来,将Nginx的debug功能关闭,也就是将nginx.conf文件中的 error_log logs/error.log debug; 配置注释掉,如下所示。

# error_log logs/error.log debug;

重新加载nginx.conf文件。

nginx_service.sh reload

最终,将Nginx加入到接入层网关,问题解决。

科普Nginx的转发规则 Nginx的location语法 location [=|~|~*|^~] /uri/ { … }

= 严格匹配。如果请求匹配这个location,那么将停止搜索并立即处理此请求

~ 区分大小写匹配(可用正则表达式)

~* 不区分大小写匹配(可用正则表达式)

!~ 区分大小写不匹配

!~* 不区分大小写不匹配

^~ 如果把这个前缀用于一个常规字符串,那么告诉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结尾的请求,并设置此location的路径是/usr/local/nginx/html/。也就是以.txt结尾的请求将访问/usr/local/nginx/html/ 路径下的txt文件

alias与root的区别

root 实际访问文件路径会拼接URL中的路径

alias 实际访问文件路径不会拼接URL中的路径

示例如下:

location ^~ /binghe/ { alias /usr/local/nginx/html/binghetic/; }

请求:

实际访问:/usr/local/nginx/html/binghetic/binghe1.html 文件

location ^~ /binghe/ { root /usr/local/nginx/html/; }

请求:

实际访问:/usr/local/nginx/html/binghe/binghe1.html 文件

last 和 break关键字的区别

(1)last 和 break 当出现在location 之外时,两者的作用是一致的没有任何差异

(2)last 和 break 当出现在location 内部时:

last 使用了last 指令,rewrite 后会跳出location 作用域,重新开始再走一次刚才的行为

break 使用了break 指令,rewrite后不会跳出location 作用域,其整个生命周期都在当前location中。

permanent 和 redirect关键字的区别

rewrite … permanent 永久性重定向,请求日志中的状态码为301

rewrite … redirect 临时重定向,请求日志中的状态码为302

综合实例

将符合某个正则表达式的URL重定向到一个固定页面

比如:我们需要将符合“/test/(\d+)/[\w-.]+” 这个正则表达式的URL重定向到一个固定的页面。符合这个正则表达式的页面可能是:、等

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

(1)使用rewrite关键字

location ~ ^.+\.txt$ { root /usr/local/nginx/html/; } location ~* ^/test/(\d+)/[\w-\.]+$ { rewrite ^/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 文件

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpsgwg.html