服务器名称
通配符名称 正则表达式名称 其他名称 国际化名称 虚拟服务器选择 优化 兼容性 |
服务器名称通过server_name指令定义,并决定哪个server块用于给定请求。另请参阅“nginx如何处理请求”。它们可以使用精确名称、通配符名称或正则表达式来定义。
server { listen 80; server_name example.org www.example.org; ... } server { listen 80; server_name *.example.org; ... } server { listen 80; server_name mail.*; ... } server { listen 80; server_name ~^(?<user>.+)\.example\.net$; ... }
当按名称搜索虚拟服务器时,如果名称匹配多种指定变体,例如同时匹配通配符名称和正则表达式,则将按以下优先级顺序选择第一个匹配的变体:
- 精确名称
- 以星号开头且最长的通配符名称,例如“
*.example.org
” - 以星号结尾且最长的通配符名称,例如“
mail.*
” - 第一个匹配的正则表达式(按其在配置文件中的出现顺序)
通配符名称
通配符名称只能在名称的开头或结尾包含星号,并且只能在点号的边界上。名称“www.*.example.org
”和“w*.example.org
”是无效的。但是,这些名称可以使用正则表达式来指定,例如“~^www\..+\.example\.org$
”和“~^w.*\.example\.org$
”。星号可以匹配多个名称部分。名称“*.example.org
”不仅匹配www.example.org
,也匹配www.sub.example.org
。
可以使用形式为“.example.org
”的特殊通配符名称来匹配精确名称“example.org
”和通配符名称“*.example.org
”。
正则表达式名称
nginx使用的正则表达式与Perl编程语言(PCRE)使用的正则表达式兼容。要使用正则表达式,服务器名称必须以波浪号字符开头
server_name ~^www\d+\.example\.net$;
否则,它将被视为精确名称,或者如果表达式包含星号,则被视为通配符名称(很可能是一个无效名称)。不要忘记设置“^
”和“$
”锚点。语法上不需要它们,但逻辑上需要。另请注意,域名中的点号应该用反斜杠转义。包含字符“{
”和“}
”的正则表达式应该被引用
server_name "~^(?<name>\w\d{1,3}+)\.example\.net$";
否则nginx将无法启动并显示错误消息
directive "server_name" is not terminated by ";" in ...
命名的正则表达式捕获可以在以后用作变量
server { server_name ~^(www\.)?(?<domain>.+)$; location / { root /sites/$domain; } }
PCRE库支持使用以下语法进行命名捕获
如果nginx启动失败并显示错误消息
?<
name
>Perl 5.10兼容语法,自PCRE-7.0起支持 ?'
name
'Perl 5.10兼容语法,自PCRE-7.0起支持 ?P<
name
>Python兼容语法,自PCRE-4.0起支持
pcre_compile() failed: unrecognized character after (?< in ...
这意味着PCRE库版本过旧,应该尝试使用“?P<
”语法替代。捕获也可以以数字形式使用name
>
server { server_name ~^(www\.)?(.+)$; location / { root /sites/$2; } }
然而,这种用法应仅限于简单情况(如上),因为数字引用很容易被覆盖。
其他名称
有一些服务器名称被特殊对待。
如果在不是默认服务器的server块中处理不带“Host”头部字段的请求,应该指定一个空名称
server { listen 80; server_name example.org www.example.org ""; ... }
如果在server块中未定义server_name,则nginx使用空名称作为服务器名称。
在这种情况下,0.8.48及更早版本的nginx使用机器的主机名作为服务器名称。
如果服务器名称被定义为“$hostname
”(0.9.4),则使用机器的主机名。
如果有人使用IP地址而不是服务器名称发送请求,则“Host”请求头部字段将包含IP地址,并且可以使用IP地址作为服务器名称来处理请求
server { listen 80; server_name example.org www.example.org "" 192.168.1.1 ; ... }
在捕获所有请求的服务器示例中,可以看到奇怪的名称“_
”
server { listen 80 default_server; server_name _; return 444; }
这个名称没有什么特别之处,它只是众多无效域名中的一个,永远不会与任何真实名称冲突。同样可以使用其他无效名称,如“--
”和“!@#
”。
0.6.25及更早版本的nginx支持特殊名称“*
”,该名称被错误地解释为捕获所有请求的名称。它从未真正充当捕获所有请求或通配符服务器名称的功能。相反,它提供了现在由server_name_in_redirect指令提供的功能。特殊名称“*
”现在已被弃用,应使用server_name_in_redirect指令。请注意,无法使用server_name指令指定捕获所有请求的名称或默认服务器。这是listen指令的属性,而不是server_name指令的属性。另请参阅“nginx如何处理请求”。可以定义在端口*:80和*:8080上监听的服务器,并指定其中一个将是端口*:8080的默认服务器,而另一个将是端口*:80的默认服务器。
server { listen 80; listen 8080 default_server; server_name example.net; ... } server { listen 80 default_server; listen 8080; server_name example.org; ... }
国际化名称
国际化域名(IDNs)应在server_name指令中使用ASCII(Punycode)表示形式指定
server { listen 80; server_name xn--e1afmkfd.xn--80akhbyknj4f; # пример.испытание ... }
虚拟服务器选择
首先,在默认服务器上下文中创建一个连接。然后,可以在以下请求处理阶段确定服务器名称,每个阶段都涉及服务器配置选择:
-
在SSL握手期间,提前,根据SNI
-
处理请求行之后
-
处理
Host
头部字段之后 -
如果在处理请求行或从
Host
头部字段中未确定服务器名称,nginx将使用空名称作为服务器名称。
在这些阶段中的每一个阶段,都可以应用不同的服务器配置。因此,应谨慎指定某些指令
- 对于ssl_protocols指令,协议列表由OpenSSL库在可以根据通过SNI请求的名称应用服务器配置之前设置,因此,协议应仅为默认服务器指定;
- client_header_buffer_size和merge_slashes指令在读取请求行之前涉及,因此,这些指令使用默认服务器配置或由SNI选择的服务器配置;
- 对于涉及处理请求头部字段的ignore_invalid_headers、large_client_header_buffers和underscores_in_headers指令,它还取决于是否根据请求行或
Host
头部字段更新了服务器配置; - 错误响应将由当前处理请求的服务器中的error_page指令处理。
优化
精确名称、以星号开头的通配符名称和以星号结尾的通配符名称存储在绑定到监听端口的三个哈希表中。哈希表的大小在配置阶段进行了优化,以便通过最少的CPU缓存未命中来查找名称。设置哈希表的详细信息在单独的文档中提供。
首先搜索精确名称哈希表。如果找不到名称,则搜索以星号开头的通配符名称哈希表。如果在此处也找不到名称,则搜索以星号结尾的通配符名称哈希表。
搜索通配符名称哈希表比搜索精确名称哈希表慢,因为名称是按域名部分搜索的。请注意,特殊通配符形式“.example.org
”存储在通配符名称哈希表中,而不是精确名称哈希表中。
正则表达式是按顺序测试的,因此是最慢且不可扩展的方法。
因此,尽可能使用精确名称更好。例如,如果服务器最常请求的名称是example.org
和www.example.org
,则显式定义它们效率更高
server { listen 80; server_name example.org www.example.org *.example.org; ... }
而不是使用简化形式
server { listen 80; server_name .example.org; ... }
如果定义了大量服务器名称,或定义了异常长的服务器名称,则可能需要在http级别调整server_names_hash_max_size和server_names_hash_bucket_size指令。根据CPU缓存行大小,server_names_hash_bucket_size指令的默认值可能等于32、64或其他值。如果默认值为32且服务器名称定义为“too.long.server.name.example.org
”,则nginx将无法启动并显示错误消息
could not build the server_names_hash, you should increase server_names_hash_bucket_size: 32
在这种情况下,应将指令值增加到下一个2的幂
http { server_names_hash_bucket_size 64; ...
如果定义了大量服务器名称,将出现另一条错误消息
could not build the server_names_hash, you should increase either server_names_hash_max_size: 512 or server_names_hash_bucket_size: 32
在这种情况下,首先尝试将server_names_hash_max_size设置为接近服务器名称数量的数字。只有在这样做没有帮助,或者nginx的启动时间无法接受的情况下,才尝试增加server_names_hash_bucket_size。
如果某个服务器是某个监听端口的唯一服务器,则nginx将完全不测试服务器名称(并且不会为该监听端口构建哈希表)。但是,有一个例外。如果服务器名称是带有捕获的正则表达式,则nginx必须执行该表达式以获取捕获。
兼容性
- 特殊服务器名称“
$hostname
”自0.9.4起支持。 - 自0.8.48起,默认服务器名称值为一个空名称“”
- 命名的正则表达式服务器名称捕获自0.8.25起支持。
- 正则表达式服务器名称捕获自0.7.40起支持。
- 空服务器名称“”自0.7.12起支持。
- 通配符服务器名称或正则表达式自0.6.25起支持作为第一个服务器名称使用。
- 正则表达式服务器名称自0.6.7起支持。
- 通配符形式
example.*
自0.6.0起支持。 - 特殊形式
.example.org
自0.3.18起支持。 - 通配符形式
*.example.org
自0.1.13起支持。
作者:Igor Sysoev 编辑:Brian Mercer |