服务器名称
通配符名称 正则表达式名称 其他名称 国际化名称 虚拟服务器选择 优化 兼容性 |
服务器名称使用 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; ... }
国际化名称
国际化域名(IDN)应在 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指令。 server_names_hash_bucket_size指令的默认值可能等于 32 或 64,或其他值,具体取决于 CPU 缓存行大小。如果默认值为 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 以来,支持正则表达式服务器名称。
-
自 0.6.0 以来,支持通配符形式
example.*
。 -
自 0.3.18 以来,支持特殊形式
.example.org
。 -
自 0.1.13 以来,支持通配符形式
*.example.org
。
作者:Igor Sysoev 编辑:Brian Mercer |