内容简介:Nginx在逻辑上将提供不同内容的配置划分为块,这些块以层次结构的形式存在(http->server->location)。客户端发出请求时,Nginx收到之后,会有一个确定应该使用哪些配置块来处理请求的过程。本文主要介绍 server 块背后的处理过程。server块是Nginx配置的子集,它定义用于处理已定义类型请求的虚拟服务器(虚拟机)。管理员通常会配置多个server块,并根据请求的域名,端口和IP地址决定哪个块应该处理哪个连接。由于Nginx允许管理员定义多个server块作为单独的虚拟Web服务
Nginx的块配置
Nginx在逻辑上将提供不同内容的配置划分为块,这些块以层次结构的形式存在(http->server->location)。客户端发出请求时,Nginx收到之后,会有一个确定应该使用哪些配置块来处理请求的过程。本文主要介绍 server 块背后的处理过程。
server块是Nginx配置的子集,它定义用于处理已定义类型请求的虚拟服务器(虚拟机)。管理员通常会配置多个server块,并根据请求的域名,端口和IP地址决定哪个块应该处理哪个连接。
Nginx如何决定哪个server块来处理请求
由于Nginx允许管理员定义多个server块作为单独的虚拟Web服务器实例,因此需要一个算法来确定将使用哪些server块来匹配请求。
Nginx在此过程中关注的主要server块指令是 listen
指令和 server_name
指令。
解析“listen”指令以找到可能的匹配
首先,Nginx查看请求的IP地址和端口,并与每个服务器的 listen
指令相匹配,构建可能解析请求的服务器块列表。
listen
指令通常定义 server 块将响应的IP地址和端口。默认情况下,任何不包含 listen
指令的 server 块默认 listen 在 0.0.0.0:80
(或者 0.0.0.0:8080
如果Nginx由普通的非root用户运行),这样的配置块响应80端口上任何接口的请求,但是这个默认值在server选择过程中没有太大的权重。
该 listen
指令可以设置为:
- IP地址/端口组合。
- 只有IP地址,它将监听默认端口80。
- 只有端口,它将监听该端口上的每个接口。
- Unix套接字的路径。
最后的选项通常在不同的服务器之间传递请求时起到作用。
在尝试确定向哪个服务器块发送请求时,Nginx将首先尝试 listen
使用以下规则根据指令的特异性来决定:
-
Nginx用默认的缺省值来替换所有不完整的lesten指令(完整:IP+port的组合)的缺省值,因此每一个server块的
listen
指令都可以看作是IP地址和端口的组合。 这种转换的例子有:-
没有
listen
指令的块使用该值0.0.0.0:80
。 -
设置为
111.111.111.111
没有端口的IP地址的块变为111.111.111.111:80
-
设置为
8888
没有IP地址的端口的块变为0.0.0.0:8888
-
没有
- 接下来Nginx会尝试去收集一个server块的列表,这个列表是基于具体的IP和端口最佳匹配。也就是说如果匹配的server块有具体的IP地址,它就不会匹配用0.0.0.0作为默认的IP地址的server块。无论什么情况,在Nginx选择server块的过程中,端口必须准确匹配。
-
如果只有一个最具体的匹配,那么该server块将用于提供请求。如果有多个server 块具有相同层次的具体匹配,那么Nginx需继续评估
server_name
指令 。
需要特别注意的是,只有 listen 指令在同一层次上有多个匹配的 server 块时,Nginx才会继续评估 server_name
指令。举个例子,如果域名example.com被解析到IP为192.168.1.10,端口为80的主机上,当客户端请求example.com时,在本例中,第一个server模块总是会提供服务,尽管 server_name
指令在第二个server模块中。
1 2 3 4 |
server{ listen 192.168.1.10; .... } |
1 2 3 4 5 |
server{ listen 80; server_name example.com; .... } |
多个server模块在具体的匹配中处于同一级别的情况下,Nginx下一步才会检查 server_name
指令。
解析server_name指令选择一个匹配
接下来,为了进一步评估具有相同特定 listen
指令的请求,Nginx会检查请求的“host”标头,此值包含客户端实际尝试访问的域或IP地址。
Nginx在候选的每一个server模块中,查看其 server_name
指令,尝试去找到最佳的匹配。Nginx通过下面的公式来进行评估:
-
Nginx首先找到
server_name
与请求的Host头信息精准匹配的server模块,如果找到了这个server模块,它将会被用于服务客户端的请求。若有多个特定的匹配项被找到,第一个会被用于提供服务。 -
如果没有找到精准的匹配项,Nginx接下来将尝试去找
server_name
与前置通配符(在配置中名称的开头用*表示)匹配的server模块。只要找到一个,这个server模块将被用于为客户端提供服务。如果找到了多个匹配,最长匹配结果的server模块将会被用于提供服务。 -
如果使用前置通配符没有找到匹配时,Nginx接下来将尝试去找
server_name
与后置通配符(在配置中名称的结尾用*表示)匹配的server模块。只要找到一个,这个server模块将被用于为客户端提供服务。如果找到了多个匹配,最长匹配结果的server模块将会被用于提供服务。 -
如果使用后置通配符没有找到匹配时,Nginx接下来将会评估用正则表达式(在名称前用~表示)定义
server_name
的server模块。带有与Host头匹配的正则表达式的第一个server_name
将被用于提供服务。 -
如果没有找到用正则表达式定义
server_name
的相匹配的server模块时,Nginx接下来会使用默认IP和端口的server模块。
每一个IP地址/端口组合都有一个默认的server模块,当用上面的方法不能确定一个操作的过程时将使用默认的server模块。对于IP地址/端口的组合来说,这将是配置中的第一个模块或者是包含 default_server
选项作为 listen
指令的一部分的server模块(这将复写first-found算法)。每一个IP地址/端口组合只能有一个 default_server
声明。
实例
如果已定义的 server_name
与Host头的值精准匹配时,这个server模块将被选择来处理请求。
在这个例子中,如果请求的Host头的值被设置为 host1.example.com,第二个server模块将被选中:
1 2 3 4 5 |
server{ listen 80; server_name *.example.com; ... } |
1 2 3 4 5 |
server{ listen 80; server_name host1.example.com; ... } |
如果精准的匹配没有被找到时,Nginx将会检查是否有一个具有适合前置通配符的 server_name
。以通配符开始的最长的 server_name
的server模块将会被选择来完成响应。
在这个例子中,如果请求的Host头是 www.example.org,第二个server模块将被选中:
1 2 3 4 5 |
server{ listen 80; server_name www.example.*; ... } |
1 2 3 4 5 |
server{ listen 80; server_name *.example.org; ... } |
1 2 3 4 |
server{ listen 80; server_name *.org; } |
若 server_name
以通配符开始的模块没有找到,Nginx将查看在表达式后面有通配符的匹配项是否存在。此时,以通配符结尾的最长的匹配项将被用于服务客户端的请求。
在这个例子中,如果请求的Host头被设置为 www.example.com,第三个模块将被选中:
1 2 3 4 5 |
server{ listen 80; server_name host1.example.com; ... } |
1 2 3 4 |
server{ listen 80; server_name example.com; } |
1 2 3 4 |
server{ listen 80; server_name www.example.*; } |
如果通配符匹配项没有找到,Nginx将会去匹配用了正则表达式的 server_name
。第一个匹配上的server模块将会被选中来响应请求。
在这个例子中,如果请求的Host头设置为 www.example.com,那么第二个server模块将被选中来完成响应。
1 2 3 4 5 |
server{ listen 80; server_name example.com; ... } |
1 2 3 4 5 |
server{ listen 80; server_name ~^(www|host1).*\.example\.com$; ... } |
1 2 3 4 5 |
server{ listen 80; server_name ~^(subdomain|set|www|host1).*\.example\.com$; ... } |
如果上述步骤都不能满足请求,则该请求将被传递到默认的server模块以获取匹配的IP地址和端口。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 深入理解express框架的匹配路由
- 给我一首歌的时间,带你深入理解正则表达式的贪婪匹配和懒惰匹配
- 对字符串匹配算法的一点理解
- 云从科技联合上交大提出DCMN匹配机制,刷新机器阅读理解记录
- Leetcode 题目:括号匹配
- Nginx 请求匹配规则
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
CSS 压缩/解压工具
在线压缩/解压 CSS 代码
XML、JSON 在线转换
在线XML、JSON转换工具