zoukankan      html  css  js  c++  java
  • nginx rewrite 踩坑

    nginx rewrite 500的故障

    今天遇到的一个问题 当访问 www.biglittleant.cn/mall 返回500,当访问 www.biglittleant.cn/mall/返回正常的页面。

    我们来还原一下当时的情况

    nginx配置文件如下:

    # cat的多行内容有$等特殊字符时,须利用转义字符
    cat >www.biglittleant.cn.conf<<EOF
    server {
        listen       80;
        server_name  www.biglittleant.cn;
    
        location / {
            root   html;
            index  index.html index.htm;
            rewrite ^/mall(.*)$ $1 last;
        }
    
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        error_log logs/www.biglittleant.cn.error.log debug;
    }
    EOF
    

    重启一下nginx

    /data/app/nginx/sbin/nginx -t
    /data/app/nginx/sbin/nginx -s reload
    

    发起测试看看结果

    [root@linux-node1 conf.d11:08:25]#curl -I http://www.biglittleant.cn/mall -x 192.168.56.11:80
    HTTP/1.1 500 Internal Server Error
    Server: nginx/1.12.1
    Date: Thu, 30 Apr 2020 03:08:35 GMT
    Content-Type: text/html
    Content-Length: 537
    Connection: close
    ETag: "5d5e5679-219"
    
    [root@linux-node1 conf.d11:08:35]#curl -I http://www.biglittleant.cn/mall/ -x 192.168.56.11:80
    HTTP/1.1 200 OK
    Server: nginx/1.12.1
    Date: Thu, 30 Apr 2020 03:09:34 GMT
    Content-Type: text/html
    Content-Length: 612
    Last-Modified: Thu, 22 Aug 2019 08:46:49 GMT
    Connection: keep-alive
    ETag: "5d5e5679-264"
    Accept-Ranges: bytes
    

    http://www.biglittleant.cn/mall 返回500,同时error日志中增加了一行记录

    the rewritten URI has a zero length, client: 192.168.56.11, server: www.biglittleant.cn, request: "HEAD http://www.biglittleant.cn/mall HTTP/1.1", host: "www.biglittleant.cn"
    

    通过日志分析可以发现是因为(.*) 没有匹配到任何内容导致的报错。

    2020/04/30 11:08:35 [debug] 103857#0: *51 http script regex: "^/mall(.*)$"
    2020/04/30 11:08:35 [notice] 103857#0: *51 "^/mall(.*)$" matches "/mall", client: 192.168.56.11, server: www.biglittleant.cn, request: "HEAD http://www.biglittleant.cn/mall HTTP/1.1", host: "www.biglittleant.cn"
    2020/04/30 11:08:35 [debug] 103857#0: *51 http script capture: ""
    2020/04/30 11:08:35 [debug] 103857#0: *51 http script regex end
    2020/04/30 11:08:35 [notice] 103857#0: *51 rewritten data: "", args: "", client: 192.168.56.11, server: www.biglittleant.cn, request: "HEAD http://www.biglittleant.cn/mall HTTP/1.1", host: "www.biglittleant.cn"
    2020/04/30 11:08:35 [error] 103857#0: *51 the rewritten URI has a zero length, client: 192.168.56.11, server: www.biglittleant.cn, request: "HEAD http://www.biglittleant.cn/mall HTTP/1.1", host: "www.biglittleant.cn"
    
    
    2020/04/30 11:09:34 [debug] 103857#0: *52 http script regex: "^/mall(.*)$"
    2020/04/30 11:09:34 [notice] 103857#0: *52 "^/mall(.*)$" matches "/mall/", client: 192.168.56.11, server: www.biglittleant.cn, request: "HEAD http://www.biglittleant.cn/mall/ HTTP/1.1", host: "www.biglittleant.cn"
    2020/04/30 11:09:34 [debug] 103857#0: *52 http script capture: "/"
    2020/04/30 11:09:34 [debug] 103857#0: *52 http script regex end
    2020/04/30 11:09:34 [notice] 103857#0: *52 rewritten data: "/", args: "", client: 192.168.56.11, server: www.biglittleant.cn, request: "HEAD http://www.biglittleant.cn/mall/ HTTP/1.1", host: "www.biglittleant.cn"
    

    解决办法1

    将location给规范起来,让只有/mall/的访问才能去rewrite。

    # cat的多行内容有$等特殊字符时,须利用转义字符
    cat >www.biglittleant.cn.conf<<EOF
    server {
        listen       80;
        server_name  www.biglittleant.cn;
        location /mall/ {
            rewrite ^/mall(.*)$  $1  last;
        }
        location / {
            root   html;
            index  index.html index.htm;
        }
    
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        error_log logs/www.biglittleant.cn.error.log debug;
    }
    EOF
    
    [root@linux-node1 conf.d11:25:23]#curl -I http://www.biglittleant.cn/mall -x 192.168.56.11:80
    HTTP/1.1 404 Not Found
    Server: nginx/1.12.1
    Date: Thu, 30 Apr 2020 03:25:27 GMT
    Content-Type: text/html
    Content-Length: 169
    Connection: keep-alive
    
    [root@linux-node1 conf.d11:25:27]#curl -I http://www.biglittleant.cn/mall/ -x 192.168.56.11:80
    HTTP/1.1 200 OK
    Server: nginx/1.12.1
    Date: Thu, 30 Apr 2020 03:25:35 GMT
    Content-Type: text/html
    Content-Length: 612
    Last-Modified: Thu, 22 Aug 2019 08:46:49 GMT
    Connection: keep-alive
    ETag: "5d5e5679-264"
    Accept-Ranges: bytes
    

    通过日志可以看到,由于没有命中 /mall/ 所以走了默认的 / 协议,自然就不会在报500的错误了。

    2020/04/30 11:25:27 [debug] 104724#0: *57 test location: "/"
    2020/04/30 11:25:27 [debug] 104724#0: *57 test location: "mall/"
    2020/04/30 11:25:27 [debug] 104724#0: *57 test location: "50x.html"
    2020/04/30 11:25:27 [debug] 104724#0: *57 using configuration "/"
    2020/04/30 11:25:27 [error] 104724#0: *57 open() "/data/app/nginx-1.12.1/html/mall" failed (2: No such file or directory), client: 192.168.56.11, server: www.biglittleant.cn, request: "HEAD http://www.biglittleant.cn/mall HTTP/1.1", host: "www.biglittleant.cn"
    

    解决办法二

    找到真实的需求,然后重新规划。

    其实开发的需求是希望 访问 /mall 很访问 /mall/ 都能访问的目录中的index, 那这种情况,我们可以使用 try_files 来优化,配置如下:

    # cat的多行内容有$等特殊字符时,须利用转义字符
    cat >www.biglittleant.cn.conf<<EOF
    server {
        listen       80;
        server_name  www.biglittleant.cn;
    
        location /mall {
            root   html;
            index  index.html index.htm;
            try_files $uri $uri/ /index.html;
    
        }
        location / {
            root   html;
            index  index.html index.htm;
        }
    
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        error_log logs/www.biglittleant.cn.error.log debug;
    }
    EOF
    
    [root@linux-node1 conf.d11:29:51]#curl -I http://www.biglittleant.cn/mall/ -x 192.168.56.11:80
    HTTP/1.1 200 OK
    Server: nginx/1.12.1
    Date: Thu, 30 Apr 2020 03:29:53 GMT
    Content-Type: text/html
    Content-Length: 612
    Last-Modified: Thu, 22 Aug 2019 08:46:49 GMT
    Connection: keep-alive
    ETag: "5d5e5679-264"
    Accept-Ranges: bytes
    
    [root@linux-node1 conf.d11:29:53]#curl -I http://www.biglittleant.cn/mall -x 192.168.56.11:80
    HTTP/1.1 200 OK
    Server: nginx/1.12.1
    Date: Thu, 30 Apr 2020 03:29:58 GMT
    Content-Type: text/html
    Content-Length: 612
    Last-Modified: Thu, 22 Aug 2019 08:46:49 GMT
    Connection: keep-alive
    ETag: "5d5e5679-264"
    Accept-Ranges: bytes
    

    分析: 通过日志可以看到,当前两个都没有命中的时候,会就url 替换成/index.html 然后重新走location匹配,命中了/ 然后返回了200.

    2020/04/30 11:29:58 [debug] 104927#0: *61 http script var: "/mall"
    2020/04/30 11:29:58 [debug] 104927#0: *61 trying to use file: "/mall" "/data/app/nginx-1.12.1/html/mall"
    2020/04/30 11:29:58 [debug] 104927#0: *61 http script var: "/mall"
    2020/04/30 11:29:58 [debug] 104927#0: *61 trying to use dir: "/mall" "/data/app/nginx-1.12.1/html/mall"
    2020/04/30 11:29:58 [debug] 104927#0: *61 trying to use file: "/index.html" "/data/app/nginx-1.12.1/html/index.html"
    2020/04/30 11:29:58 [debug] 104927#0: *61 internal redirect: "/index.html?"
    
    2020/04/30 11:29:58 [debug] 104927#0: *61 rewrite phase: 1
    2020/04/30 11:29:58 [debug] 104927#0: *61 test location: "/"
    2020/04/30 11:29:58 [debug] 104927#0: *61 test location: "mall"
    2020/04/30 11:29:58 [debug] 104927#0: *61 test location: "50x.html"
    2020/04/30 11:29:58 [debug] 104927#0: *61 using configuration "/"
    
    2020/04/30 11:29:58 [debug] 104927#0: *61 http filename: "/data/app/nginx-1.12.1/html/index.html"
    

    遇到的问题

    刚开始测试的时候 使用的是cat 重定向写入文件,cat 会将$1 给转义掉。导致测试结果不准确。

    cat >www.biglittleant.cn.conf<<EOF
    server {
        listen       80;
        server_name  www.biglittleant.cn;
    
        location / {
            root   html;
            index  index.html index.htm;
            rewrite ^/mall(.*)$ $1 last;
        }
    
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        error_log logs/www.biglittleant.cn.error.log debug;
    }
    EOF
    
    diff www.biglittleant.cn.conf www.biglittleant.cn.conf.bak
    5c5
    <         rewrite ^/mall(.*)$    last;
    ---
    >         rewrite ^/mall(.*)$  $1  last;
    

    解决办法:

    cat的多行内容有$等特殊字符时,须利用转义字符。

  • 相关阅读:
    python数据结构之字典
    Python数据结构之列表
    使用QrCode生成二维码
    JavaScript在不同环境下的全局对象
    记一次使用 removeEventListener 移除事件监听失败的经历
    Model、View、ViewModel结构以及全局视图模型注入器的说明
    MVVMLight介绍以及在项目中的使用
    WPF/Silverlight深度解决方案:(一)解锁被Storyboard束缚的关联属性
    进程发送消息
    .net4.0中wpf单例启动
  • 原文地址:https://www.cnblogs.com/biglittleant/p/12808074.html
Copyright © 2011-2022 走看看