【实际操作解决自己对nginx的listen和server_name以及dns的疑惑】

1. 配置说明

/usr/local/nginx/conf/nginx.conf

#user  nobody;
worker_processes  1;
error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
   # default_type  application/octet-stream;
    default_type  text/plain;
    log_format  p  '$remote_addr - $remote_user [$time_local] "$request" ';
    log_format  access  '$remote_addr ';
    access_log  logs/access.log  p;
    sendfile        on;
    #tcp_nopush     on;
    #keepalive_timeout  0;
    keepalive_timeout  65;
    #gzip  on;
    include /etc/nginx/*.conf;
}

注意下面的配置都要放在other.conf.d目录下面, 不能和nginx.conf配置在同一目录,因为使用了include /etc/nginx/*.conf;(和nginx.conf也是匹配的)
/usr/local/nginx/conf/other.conf.d/a.conf

server {
        listen          81;
        server_name     a.com;
#       access_log  logs/access_enjoy.log  access;

        location / {
            root   /etc/nginx/html;
            index  a.html;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

/usr/local/nginx/conf/other.conf.d/b.conf

server {
        listen       81; # default_server;
        server_name  b.com;

        location / {
            root   /etc/nginx/html;
            index  b.html;
        }
        location /echo {
                echo  'I am  b';
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

/usr/local/nginx/conf/other.conf.d/c.conf

server {
        listen       8080;
        server_name  c.com;

        location / {
            root   /etc/nginx/html;
            index  c.html;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

dns配置

127.0.0.1	a.com
127.0.0.1	b.com
127.0.0.1	c.com
127.0.0.1	z.com

2. 先说我的结论

由于自己使用的本机的docker desktop, 开始对于dns和server_name好迷糊,导致开始配置总是有的可以访问有的不能访问

问题本质是我对dns的域名和server_name的理解有问题, 我们的域名和server_name两个虽然是同一个字符串, 但是在这个网络过程中不同阶段作用是不一样的, 由于我使用的本机, 开始以为nginx会帮我做类似dns注册解析功能, 所以开始一致有问题

示例: http://you.com:81(假设docker映射端口是 81->81)

当我们本机使用域名访问时候,同样需要dns解析,并且千万记住, 我们的那个nginx中的server_name不能参与任何的dns的解析过程(nginx的server_name也有自己的作用, 后面再说),

  1. 我们的域名通过本机的hosts解析出ip(因为docker在本机,所以我们配置必须是127.0.01 you.com之类),
  2. 然后请求拿着127.0.0.1知道要在本机访问, 于是拿着个81->81端口进入了docker的81端口, 匹配server的listen端口(这一步并不是去匹配域名, 也是为什么listen写在了server_name前面)
  3. 如果所有的server只有一个和81端口匹配, 就直接命中这个server, 然后进行location解析
  4. 如果没有server和这个81端口匹配, 直接拒绝请求
  5. 如果有多个server和81端口匹配
    server_name和域名相同的server优先匹配
    如果没有server_name和域名匹配, 就使用默认server(如 listen 81 default_server;)
    如果没有指定默认server, 就命中匹配的第一个server(同一个配置从上到下, 不同文件,文件名字典序)命中

从上面的过程中,我们可以看出来,域名只在dns解析时候其到很重要的作用,一旦我们解析找到了主机时候,域名作用就没了, 所以说端口代表了一个处理程序, server list port放在第一位, default_server放在端口后面而不是server_name后面,都充分体现了端口的重要性,所以只要端口命中就一定会有一个server来location这个请求(能不能处理这个请求还要看后面的匹配), 甚至我们不配置server_name 这个server同样可以工作

总之, 域名用于dns找到主机, 端口用来找到server, server_name只是在配置了多个相同端口的server时候起到一个过滤选择的作用,非必须的

3. 基于上面的理解,我们来验证

将b.conf的server配置成default_server时候

http://b.com:81/
结果
在这里插入图片描述
http://a.com:81/
结果
在这里插入图片描述

http://z.com:81/ (注意没有z.com的server_name)
结果
在这里插入图片描述

不设置default_server时候

http://b.com:81/
结果
在这里插入图片描述
http://a.com:81/
结果
在这里插入图片描述

http://z.com:81/ (注意没有z.com的server_name)
结果: 注意,由b.html变成了a.html
在这里插入图片描述

http://c.com:8080/

结果: 下一个测试基于这个结果参照
在这里插入图片描述
上面测试结果知道了: 端口冲突, server_name筛选, default_server作为兜底条件, 保证一定能选出一个

测试端口命中, server_name不命中的情况

http://a.com:8080/
http://b.com:8080/
http://z.com:8080/
三个结果都是
在这里插入图片描述
这个测试说明端口命中就没有server_name和default_server什么事了

4. location理解

#location指令优先级验证:
#	=精准匹配,最优,匹配就直接返回
#	^~,空 为一般匹配,收集所有匹配,取最长匹配执行(此时不返回,还会执行下面的正则匹配)
#	~,~* 为正则匹配,按顺序依次匹配,命中即返回(可能会覆盖普通匹配)

server {

	listen       80;
	server_name  loc.com;

	#精准匹配测试
	#第1,2条虽然匹配,但第三条是精准匹配,出第三条结果
	#测试路径/equal/a/b/c
	location ~ /equal/* {#被命中,但被下面的推断:location = /equal/a/b/c
		echo '/equal/*';
	}
	location /equal/a/b {#被命中,但被下面的推断:location = /equal/a/b/c
		echo '/equal/a/b';
	}
	location = /equal/a/b/c {#被命中,直接执行,不等待
		echo '/equal/a/b/c';
	}

	#普通匹配测试
	#第1,2条虽然匹配,第三条匹配更长,出第三条结果
	#测试路径/match/a/b/c
	location /match/a {#被命中,但不是最长
		return 200  "/match/a";
	}
	location /match/a/b {#被命中,但不是最长
		return 200  "/match/a/b";	
	}
	location /match/a/b/c {#被命中,且最长
		 return 200  "/match/a/b/c";
	}
	location /match/a/b/c/d {#不命中
		return 200  "/match/a/b/c/d"; 
	}

	#正则匹配覆盖普通匹配测试
	#会覆盖普通匹配,不会覆盖=和^~
	location =/re/a.js {#访问/re/a.js,不会被后面的正则覆盖
		echo 'match =';
	}
	location ^~ /re/a/b {#访问/re/a/b开头的路径,不会被后面的正则覆盖
		echo 'math ^~/re/a/b*';
	}
	location /re/a.htm {#访问/re/a.htm,会被后面的正则覆盖
		 echo 'match /re/a.htm';
	}
	location ~ /re/(.*)\.(htm|js|css)$ {#覆盖/re/a.htm路径
		echo "cover /re/$1.$2";
	}

	#正则匹配成功一条后,便不再走其它正则
	#最长正则匹配是第三个,但匹配第一个后便不往下走
	#测试路径/rex/a/b/c.htm
	location ~ /rex/.*\.(htm|js|css)$ {#覆盖/re/a.htm路径
		echo "match first";
	}
	location ~ /rex/a/(.*)\.(htm|js|css)$ {#覆盖/re/a.htm路径
		echo "match second";
	}
	location ~ /rex/a/b/(.*)\.(htm|js|css)$ {#覆盖/re/a.htm路径
		echo "match third";
	}

	location / {
            root   /etc/nginx/html;
            index  c.html;
        }

}

5. proxy理解

server {
        listen       80;
        server_name	pxy.com;

	#后台服务原始路径:http://192.168.0.132:8088/mvc/index?id=2

	#无/,访问路径:http://pxy.enjoy.com/mvc/index?id=2
	location /mvc {
               #此处未关闭,传递整个路径/nginx/enjoy/getInfo到目标ip:port
               proxy_pass http://192.168.0.132:8088;
        }

        #有/,访问路径 :http://pxy.enjoy.com/nginx/mvc/index?id=2
        location /nginx/mvc {#匹配路径/dynamic,剩余路径/nginx/enjoy/getInfo
                proxy_pass http://192.168.0.132:8088/mvc;
        }

	#访问路径:http://pxy.enjoy.com/static/d.html 	
	location /static {#匹配路径/static,剩余路径/a.html
		root /etc/nginx/html/;#root声明,在html文件夹,查找/static/a.html文件
        }
	#访问路径:http://pxy.enjoy.com/target/d.html 
	location /target {#匹配路径/target,剩余路径/a.html
                alias /etc/nginx/html/static/;##alias声明,在static/文件夹,查找a.html文件
        }	

       
    }

6. rewrite理解

server {

	listen       80;
	server_name  rew.com;

	location /a.html {
		echo 'I am a.html';
	}
	location /b.html {
		echo 'I am b.html';
	}

	#此路径请求:http://rew.enjoy.com/aa.html
	location /aa.html {##内部重定向
		rewrite ^/  /a.html break;##停止指令,流程不变往下走		
		rewrite ^/  /b.html break;	
		root   /etc/nginx/html/;
	}
	

	#此路径请求:http://rew.enjoy.com/ab.html
	location /ab.html {
		rewrite ^/  /a.html last;##停止指令,但重新location匹配
		rewrite ^/  /b.html last;
		rewrite ^/  /c.html;
		root   /etc/nginx/html/;		
	}

	#此路径请求:http://rew.enjoy.com/bb
	location /bb {
		rewrite ^/  /b.html redirect;##302临时重定向
		set $aa 12;
		root   html/;
	}

	#此路径请求:http://rew.enjoy.com/ba
	location /ba {
		rewrite ^/  /b.html permanent;##301永久重定向
		root   html/;
	}

	#此路径请求:http://rew.enjoy.com/cc.html
	location /cc.html {
                rewrite ^/  /c.html;##指令不停,继续往下
                rewrite ^/  /b.html;
                rewrite ^/  /a.html;##最后一条,生效的是这条
                root   /etc/nginx/html/;
        }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岁月玲珑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值