Appearance
服务器名称
提示
来自deepseek解释
原文链接:https://nginx.org/en/docs/http/server_names.html
服务器名称通过 server_name 指令定义,用于决定哪个 server 块处理给定的请求。另请参阅“nginx 如何处理请求”。
服务器名称可以使用精确名称、通配符名称或正则表达式来定义:
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 ~^(?.+)\.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)所使用的兼容。要使用正则表达式,服务器名称必须以波浪号字符开头:
nginx
server_name ~^www\d+\.example\.net$;否则它将被视为精确名称,或者如果表达式包含星号,则视为通配符名称(并且很可能被视为无效)。
不要忘记设置 “^” 和 “$” 锚点。它们在语法上不是必需的,但在逻辑上是必需的。另请注意,域名中的点应使用反斜杠进行转义。
包含字符 “{” 和 “}” 的正则表达式应该被引号括起来:
nginx
server_name "~^(?\w\d{1,3}+)\.example\.net$";否则 nginx 将无法启动并显示错误信息:directive "server_name" is not terminated by ";" in ...
命名正则表达式捕获可以在之后用作变量:
nginx
server {
server_name ~^(www\.)?(?.+)$;
location / {
root /sites/$domain;
}
}PCRE 库支持使用以下语法进行命名捕获:
?<name>— Perl 5.10 兼容语法,自 PCRE-7.0 起支持?'name'— Perl 5.10 兼容语法,自 PCRE-7.0 起支持?P<name>— Python 兼容语法,自 PCRE-4.0 起支持
如果 nginx 无法启动并显示错误信息:pcre_compile() failed: unrecognized character after (?< in ...,这意味着 PCRE 库较旧,应尝试使用 “?P<” 语法。
捕获也可以以数字形式使用:
nginx
server {
server_name ~^(www\.)?(.+)$;
location / {
root /sites/$2;
}
}然而,这种用法应限于简单的情况(如上述),因为数字引用很容易被覆盖。
其他名称
有一些服务器名称会被特殊处理。
如果需要在非默认的 server 块中处理没有 “Host” 头字段的请求,则应指定一个空名称:
nginx
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 地址作为服务器名称来处理请求:
nginx
server {
listen 80;
server_name example.org www.example.org "" 192.168.1.1 ;
...
}在 catch-all 服务器示例中,可以看到奇怪的名称 “_”:
nginx
server {
listen 80 default_server;
server_name _;
return 444;
}这个名称没有什么特别之处,它只是众多永远不会与任何真实名称相交的无效域名之一。其他无效名称如 “--” 和 “!@#” 也同样可以使用。
nginx 0.6.25 及更早版本支持特殊名称 “”,该名称被错误地解释为 catch-all 名称。它从未作为 catch-all 或通配符服务器名称使用。相反,它提供了现在由 server_name_in_redirect 指令提供的功能。特殊名称 “” 现已弃用,应使用 server_name_in_redirect 指令。
请注意,无法使用 server_name 指令指定 catch-all 名称或默认服务器。这是 listen 指令的属性,而不是 server_name 指令的属性。另请参阅“nginx 如何处理请求”。
可以定义监听端口 *:80 和 *:8080 的服务器,并指定其中一个作为端口 *:8080 的默认服务器,而另一个作为端口 *:80 的默认服务器:
nginx
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)表示法指定:
nginx
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,那么明确定义它们:
nginx
server {
listen 80;
server_name example.org www.example.org *.example.org;
...
}比使用简化形式更高效:
nginx
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 的幂:
nginx
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 起支持。