11 Nginx常见问题

徐亮伟, 江湖人称标杆徐。多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。擅长Web集群架构与自动化运维,曾负责国内某大型电商运维工作。
个人博客"徐亮伟架构师之路"累计受益数万人。

老男孩Linux云计算运维QQ交流群: 384467551 226199307
老男孩教育官网 http://www.oldboyedu.com

1.Nginx多Server,导致Server_name优先级

1.准备nginx对应的配置文件

[root@web02 conf.d]# cat code1.conf
server {
    listen 80;
    server_name localhost;
    location / {
        root /code1;
        index index.html;
    }
}
[root@web02 conf.d]# cat code2.conf
server {
    listen 80;
    server_name localhost;
    location / {
        root /code2;
        index index.html;
    }
}
[root@web02 conf.d]# cat code3.conf
server {
    listen 80;
    server_name localhost;
    location / {
        root /code3;
        index index.html;
    }
}

2.准备站点目录

[root@web02 conf.d]# mkdir /code{1..3} -p
[root@web02 conf.d]# for i in {1..3};do echo "Code$i" > /code$i/index.html;done
[root@web02 conf.d]# cat /code1/index.html 
Code1
[root@web02 conf.d]# cat /code2/index.html 
Code2
[root@web02 conf.d]# cat /code3/index.html 
Code3

3.检查语法, 并重新加载Nginx

[root@web02 conf.d]# nginx -t
nginx: [warn] conflicting server name "localhost" on 0.0.0.0:80, ignored
nginx: [warn] conflicting server name "localhost" on 0.0.0.0:80, ignored
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

# 重启Nginx
[root@Nginx ~]# systemctl restart nginx

4.测试访问效果

#1.当用户第一次访问, 由code1.conf返回输出信息
[root@Nginx ~]# curl localhost
Code 1

#2.此时将code1.conf修改为code5.conf后进行重载Nginx
[root@Nginx ~]# mv code1.conf code5.conf
[root@Nginx ~]# systemctl reload nginx

#3.再次访问时, 由code2.conf返回输出信息
[root@Nginx ~]# curl localhost
Code 2

#小结: 当出现多个相同的Server_Name情况下,配置文件排序优先使用,所以建议配置相同端口, 不同域名(生产必配)

5.多ServerName优先级总结, 在开始处理一个HTTP请求时,Nginx会读取 header(请求头)中的 host,与每个 server中的 server_name进行匹配,来决定用哪一个 server标签来完成处理这个请求。有可能一个Host与多个server中的server_name都匹配,这个时候就会更具匹配优先级来选择实际处理的 server块。优先级匹配结果如下:

1.首先选择所有的字符串完全匹配的server_name。(完全匹配)
2.选择通配符在前面的server_name,如*.bgx.com
3.选择通配符在后面的server_name,如bgx.*
4.最后选择使用正则表达式匹配的server_name
5.如果全部都没有匹配到,那么将选择在listen配置项后加入[default|default_server]的server块
6.如果没写,那么就找到匹配listen端口的第一个Server块的配置文件

2.Nginx禁止IP访问, 只允许域名访问

1.接收到 ip访问或非指定域名访问时会返回500错误

server {
    listen 80;
    server_name www.biaoganxu.com   # 这里指定自己的域名
}
server{
    listen 80 default_server;       # 默认优先返回
    server_name _;                  # 空主机头或IP
    return 500;                     # 返回500错误
}

2.可以将流量集中导入自己的网站,只要做以下跳转设置就可以

server {
    listen 80 default_server;
    return 302 https://www.xuliangwei.com;
}

3.Nginx Include 包含文件

一台服务器配置多个server网站,会导致nginx.conf主配置文件变得非常庞大而且可读性非常的差.
使用Include的目的是为了简化主配置文件,便于人类可读。

4.Nginx alias 与 root 路径匹配

alias是一个目录别名的定义,root则是最上层目录的定义

root路径配置实例:

#用户访问/image/db.jpg,实际上Nginx会上/code/image/目录下找去找db.jpg文件。
location /image/ {
    root /code/;
}

alias配置实例:

#用户访问/image/db.jpg,实际上Nginx会上/code/目录下找去找db.jpg文件
location /image/ {
    alias /code/;
}

5.Nginx Try_file路径匹配, 按顺序检查文件是否存在

location /{
try_files $uri $uri/ /index.php;
}

#1.检查用户请求的uri内容是否存在本地,存在则解析
#2.将请求加/, 类似于重定向处理 
#3.最后交给index.php处理 

1.演示环境准备

[root@Nginx ~]# echo "Try-Page" > /soft/code/index.html
[root@Nginx ~]# echo "Tomcat-Page" > /soft/app/apache-tomcat-9.0.7/webapps/ROOT/index.html

#启动tomcat
[root@Nginx ~]# sh /soft/app/apache-tomcat-9.0.7/bin/startup.sh
#检查tomcat端口
[root@Nginx ~]# netstat -lntp|grep 8080
tcp6       0      0 :::8080                 :::*                    LISTEN      104952/java 

2.配置Nginxtryfiles

[root@Nginx ~]# cat /etc/nginx/conf.d/try.conf 
server {
        listen 80;
        server_name 192.168.69.113;
        root /soft/code;
        index index.html;
        location / {
                try_files $uri @java_page;
        }
        location @java_page {
                proxy_pass http://127.0.0.1:8080;
        }
}

#重启Nginx
[root@Nginx ~]# nginx -s reload

3.测试tryfiles

[root@Nginx ~]# curl http://192.168.69.113/index.html
Try-Page

#将/soft/code/index.html文件移走
[root@Nginx ~]# mv /soft/code/{index.html,index.html_bak}

#发现由Tomcat吐回了请求
[root@Nginx ~]# curl http://192.168.69.113/index.html    
Tomcat-Page