服务器名称

通配符名称
正则表达式名称
其他名称
国际化名称
虚拟服务器选择
优化
兼容性

服务器名称使用 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$;
    ...
}

当按名称搜索虚拟服务器时,如果名称与多个指定的变体匹配,例如通配符名称和正则表达式都匹配,则将选择第一个匹配的变体,其优先级顺序如下:

  1. 精确名称
  2. 以星号开头的最长通配符名称,例如“*.example.org
  3. 以星号结尾的最长通配符名称,例如“mail.*
  4. 第一个匹配的正则表达式(在配置文件中出现的顺序)

通配符名称

通配符名称仅可在名称的开头或结尾以及仅在点边界处包含星号。“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 库使用以下语法支持命名捕获:

?<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<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 将使用空名称作为服务器名称。

在此情况下,Nginx 0.8.48 之前的版本使用机器的主机名作为服务器名称。

如果服务器名称定义为“$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;
}

此名称没有什么特别之处,它只是无数个无效域名中的一个,永远不会与任何真实名称相交。其他无效名称(如“--”和“!@#”)也可以同样使用。

Nginx 0.6.25 之前的版本支持特殊名称“*”,该名称被错误地解释为通配符名称。它从未用作通配符或通配符服务器名称。相反,它提供了现在由 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;
    ...
}

国际化名称

应在 server_name 指令中使用 ASCII(Punycode)表示法指定国际化域名 (IDN)。

server {
    listen       80;
    server_name  xn--e1afmkfd.xn--80akhbyknj4f;  # пример.испытание
    ...
}

虚拟服务器选择

首先,在默认服务器上下文中创建连接。然后,可以在以下请求处理阶段确定服务器名称,每个阶段都参与服务器配置选择:

在每个阶段,都可以应用不同的服务器配置。因此,应谨慎指定某些指令:

优化

精确名称、以星号开头的通配符名称和以星号结尾的通配符名称存储在三个绑定到侦听端口的哈希表中。在配置阶段优化哈希表的大小,以便可以使用最少的 CPU 缓存未命中找到名称。设置哈希表的详细信息在单独的 文档 中提供。

首先搜索精确名称哈希表。如果未找到名称,则搜索包含以星号开头的通配符名称的哈希表。如果在那里找不到名称,则搜索包含以星号结尾的通配符名称的哈希表。

搜索通配符名称哈希表比搜索精确名称哈希表慢,因为名称按域名部分进行搜索。请注意,特殊通配符表单“.example.org”存储在通配符名称哈希表中,而不是在精确名称哈希表中。

正则表达式按顺序进行测试,因此是最慢且不可扩展的方法。

出于这些原因,最好在可能的情况下使用精确名称。例如,如果服务器最常请求的名称是 example.orgwww.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_sizeserver_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 必须执行表达式以获取捕获。

兼容性

作者:Igor Sysoev
编辑:Brian Mercer