016.Nginx常见问题

一、Nginx多Server优先级

在开始处理一个http请求时,nginx会取出header头部的Host变量,与nginx.conf中每个server的server_name进行匹配,由此决定到底由哪个server来处理这个请求。但nginx如果配置多个相同的server_name,会导致server_name出现优先级访问冲突

  1. 准备nginx对应配置文件
[root@web01 ~]# vim /usr/local/nginx/conf.d/web01.example.com.conf
server {
        listen 80;
        server_name localhost test1.com;

        location / {
                root /usr/local/nginx/html/;
                index test1.html;
        }
}
server {
        listen 80;
        server_name localhost test2.com;

        location / {
                root /usr/local/nginx/html/;
                index test2.html;
        }
}
server {
        listen 80;
        server_name localhost test3.com;

        location / {
                root /usr/local/nginx/html/;
                index test3.html;
        }
}
  1. 准备站点环境
[root@web01 ~]# echo "test1" > /usr/local/nginx/html/test1.html
[root@web01 ~]# echo "test2" > /usr/local/nginx/html/test2.html
[root@web01 ~]# echo "test3" > /usr/local/nginx/html/test3.html
[root@web01 ~]# systemctl restart nginx	# 此时做nginx语法检测会有提示localhost域名冲突,忽略警告
  1. 测试访问效果
[root@web01 ~]# curl localhost	# 用户首次访问返回code1

# 将web01的所有.conf配置文件注释,并调整测试配置文件内的test1的顺序
[root@web01 ~]# curl localhost  # 返回的值是最靠前的test配置值

在做好本地hosts文件解析的前提下,通过域名访问三个server正常,但通过IP地址直接访问web01节点时,Nginx排序最靠前的配置文件会生效,通过调整配置文件的排序的先后顺序可以测试

  1. ServerName优先级结论

当用户请求的域名能与web节点中的多个server_name匹配时,Nginx会通过匹配优先级来选择server区块来处理,优先级顺序由高到低如下

  1. 所有字符完全匹配的server_name
  2. 通配符在前的server_name,如*.example.com
  3. 通配符在后的server_name,如web.example.*
  4. 使用正则表达式匹配的server_name
  5. 如果全都没有匹配到,将选择在listen配置项后加入[default_server]的server块
  6. 如果没写[default_server],那么会匹配listen端口的第一个server块的配置文件

二、Nginx禁止IP直接访问

当用户通过IP或未知域名来访问站点时,希望Nginx能够禁止显示任何有效内容,可以给用户返回500,许多机房会要求站点关闭空主机头,防止未经过备案的域名指向站点

  1. 设置IP访问默认server块
[root@web01 ~]# vim /usr/local/nginx/conf.d/web01.example.com.conf
...
server {
        listen 80 default_server;   # 设置为空主机头时默认返回的server区块
        server_name _;

        location / {
                root /usr/local/nginx/html/;
                index test4.html;
        }
}
[root@web01 ~]# echo "test4" > /usr/local/nginx/html/test4.html
[root@web01 ~]# systemctl restart nginx
  1. 访问测试
[root@web01 ~]# curl 172.16.1.7 # 直接通过IP访问获取结果
  1. 禁止直接通过IP访问
[root@web01 ~]# vim /usr/local/nginx/conf.d/web01.example.com.conf
server {
        listen 80 default_server;
        server_name _;
        return 503;
        # return 302 http://test1.com;  # 导流
}

除了禁止直接通过IP访问站点,还有一种用的比较多的方式就是导流,将流量指向站点首页

三、Nginx包含文件include

一台服务器的多个server站点如果都写在某一个或集中写在数个配置文件中,会导致配置文件变得庞大且可读性差,使后期维护难度增大;对于部分站点的调整和启停,集中式的配置文件中需要手动去注释配置文件,风险更高,通过include直接调整配置文件的方式更加便捷

四、Nginx路径root与alias

root与alias路径匹配主要区别在于nginx如何解释location的uri,这会使两者分别以不同的方式将请求映射到服务器路径上,alias是一个目录别名的定义,root则是最上层目录的定义

  • root的处理结果:root路径+location路径
  • alias的处理结果:使用alias路径替换location路径
[root@web01 ~]# vim /usr/local/nginx/conf.d/web01.example.com.conf
server {
        listen 80;
        server_name test5.com;

        location / {
                root /usr/local/nginx/html/;
                index jc.html;
        }

        location /nginx.png {
                alias /usr/local/nginx/html/images/;
                index nginx.png;
        }
}

经过测试,正则表达式的location匹配配合alias使用,无法获取到想要的结果,例如location ~* ^.*\.(png|jpg|gif)$location ~ \.(png|jpg|gif)$location ~ \.png$等正则匹配规则都进行尝试了,结果都不尽如人意

五、Nginx try_files路径匹配

nginx的try_file路径匹配,按顺序检查是否存在

[root@web01 ~]# vim /usr/local/nginx/conf.d/try.example.com.conf
server {
        listen 80;
        server_name try.example.com;
        charset utf-8,gbk;
        root /usr/local/nginx/html/;
        index web01.html;
        location / {
                try_files $uri $uri/ /50x.html;
        }
}

以请求http://try.example.com/index.html为例

  1. $uri代表检查用户请求的URI文件是否存在,这代表用户的请求路径必须是具体文件才会匹配,以上述请求为例,$uri就代表/index.html,Nginx会查询/usr/local/nginx/html/index.html是否存在,若不存在则匹配下一路径
  2. $uri/代表检查用户请求的URI目录是否存在,匹配具体目录,以上述请求为例,$uri/代表/,Nginx会查询/目录是否存在,存在即返回配置文件中的缺省文件给用户,即/web01.html文件
  3. 前两者都未匹配的前提下,返回50x.html页面给用户

配置文件中的$uri/也可以写成$uri/web01.html,如此可以代替index web01.html的作用

内部跳转

  1. 修改nginx配置文件
[root@web01 ~]# vim /usr/local/nginx/conf.d/try.example.com.conf
...
location / {
    try_files $uri $uri/web01.html @java_page;    # @java_page是内部跳转的语法
}
location @java_page {   # 调用内部跳转
    proxy_pass http://172.16.1.8:8080;
}
  1. 新建nginx测试页面
[root@web01 ~]# echo "Nginx" > /usr/local/nginx/html/web01.html
  1. 新建tomcat测试页面
[root@web02 ~]# echo "Tomcat" > /usr/share/tomcat/webapps/ROOT/try.html

此时通过浏览器或curl命令测试http://try.example.com/try.html能够直接跳转到tomcat响应

注:

try_files查找下一顺序路径的前提条件是,上一路径必须是未找到相应文件或目录(即404),而不是无权限在相应目录下查找(即403);使用try_files参数的前提是,站点必须是静态或伪静态的

六、Nginx调整上传文件大小

指令:

Syntax: client_max_body_size size;
Default: client_max_body_size 1m;
Context: http, server, location;

文件上传大小配置建议单独配置在每个server站点配置下,不同站点应对不同场景

七、Nginx优雅展示错误页面

error_page错误日志

[root@web01 ~]# vim /usr/local/nginx/conf.d/test6.example.com.conf
server {
    listen 80;
    server_name test6.example.com;
    charset utf-8,gbk;
    root /usr/local/nginx/html/;
    location / {
            index index.html;
    }
    location ~ \.php$ {
            fastcgi_pass 127.0.0.1:9000;
    }

    error_page 404 403 /40x.html;   # 若服务器返回404、403状态码,则跳转至/40x.html页面
    error_page 500 502 503 504 /50x.html;

    location = /40x.html {  # 定义40x的跳转匹配
        root /usr/local/nginx/html/;
    }
    location = /50x.html {
        root /usr/local/nginx/html/;
    }
}
[root@web01 ~]# echo "40X" > /usr/local/nginx/html/40x.html
[root@web01 ~]# systemctl restart nginx

编译安装nginx默认没有/40x.html文件,需要手动创建测试文件,/50x.html默认存在,无需新建;除了可以指向html文件,也可以更简单直接的指向某张图片

posted @ 2023-06-19 09:23  hebo  阅读(73)  评论(0)    收藏  举报