Nginx监听不同端口时default_server问题
在学习配置Nginx时对default_server产生一点疑问,因此通过实验和查阅官方文档的方式对该问题进行初步的解决,本文用于记录该问题和研究过程,希望能对有同样疑问的同学有帮助,同时欢迎各位同学指点交流。
Nginx中的default_server
Nginx配置文件nginx.conf中的server块中的listen可以后可以设置default_server
- nginx 的 default_server 指令可以定义默认的 server 去处理一些没有匹配到 server_name 的请求
- 如果没有显式定义,则会选取第一个定义的 server 作为 default_server。
但是在视频学习过程中偶然发现以上规则似乎失效了, 其场景是一个server监听80端口(称为server1), 一个server监听8080端口(称为server2), 其中server1在前且没有配置default_server, 在匹配失败之后依然是server2处理了请求
场景复现
为了复现场景, 配置了以下四个server
# server1匹配 www.server1.com:80
server {
listen 80;
server_name www.server1.com;
default_type text/plain;
return 200 "=========this is server1 that listen on port 80==========";
}
# server2匹配 www.server2.com:8080
server {
listen 8080;
server_name www.server2.com;
default_type text/plain;
return 200 "=========this is server2 that listen on port 8080==========";
}
# 80端口的的默认server
server {
listen 80 default_server;
server_name _;
default_type text/plain;
return 200 "=========this is default server that listen on port 80==========";
}
# 给8080端口配置一个额外的server,但不显式的指定为默认server
server {
listen 8080;
server_name _;
default_type text/plain;
return 200 "=========this is another server that listen on port 8080==========";
}
实验过程
在实验之前需要在\etc\hosts 文件中配置一下域名解析, 加入一行127.0.0.1 www.server1.com www.server2.com www.server3.com 即可。Windows系统在C:\Windows\System32\drivers\etc 路径下
- 访问
www.server1.com
请求被server1正常匹配
- 访问
www.server2.com
请求被80端口的默认server处理
- 访问
www.server3.com
请求被80端口的默认server处理
- 访问
www.server1.com:8080
请求被server2处理,此时8080端口没有显式指定default_server,选择第一个监听8080端口的server,即server2处理请求
- 访问
www.server2.com:8080
请求被server2正常匹配
- 访问
www.server3.com:8080
请求被server2处理,同www.server1.com:8080 的情况
官方文档
?? 注意:由于文档版本问题,这里使用default参数,0.8.21版本之后使用default_server代替
listen
If the directive has the default parameter, then the enclosing server {…} block will be the default server for the address:port pair.
若listen指令有default参数,那么该server块则是该address:port对的默认server。
If there are no directives with thedefault parameter, then the default server will be the first server block in which theaddress:port pair appears.
若没有带有default参数的listen指令那么默认server为监听address:port的第一个server
server_name
- header of the incoming HTTP request against the server { … } blocks in the Nginx configuration files and selects the first one that matches. This is how virtual servers are defined. Server names are processed in the following order:
-
full, static names -
names with a wildcard at the start of the name — *.example.com -
names with a wildcard at the end of the name — www.example.* -
names with regular expressions 这之前都是关于server_name匹配的规则
If there is no match, a [#server server { … }] block in the configuration file will be used based on the following order:
若以上规则无法匹配到server,则使用下面的规则选择server:
-
the server block with a matchinglisten directive marked asdefault 匹配listen指令且被default显示标记的server块 -
the first server block with a matchinglisten directive (or implicitlisten 80; ) 匹配listen指令的第一个server块 ??注意:这里有点不理解括号里啥意思,意思应该是listen 等效于listen 80
结论
- 经过后续实验证明实际上, default_server可以配置多个, 但是需要配置为不同端口, 同端口配置多个default_server无法通过
nginx -t 检查。 - 结合简单实验和官方文档,对于该问题可以简单理解为匹配server时是根据请求的
IP地址:端口号 匹配的, 可以理解为多个server会根据监听的IP:端口号 分为若干组, 若server匹配失败则由该组的default_server进行请求处理(没有显式指定default_server则为监听该IP端口对的第一个server)
|