Server names

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

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

  • exact name

  • 以星号开头的最长通配符名称,例如“ *.example.org

  • 以星号结尾的最长通配符名称,例如“ mail.*

  • 第一个匹配的正则表达式(按在配置文件中出现的顺序)

Wildcard names

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

Note

?<name>Perl 5.10 兼容语法,自 PCRE-7.0 起受支持
?'name'Perl 5.10 兼容语法,自 PCRE-7.0 起受支持
?P<name>自 PCRE-4.0 起受支持的 Python 兼容语法

如果 nginx 无法启动并显示错误消息:

pcre_compile() failed: unrecognized character after (?< in ...

这意味着 PCRE 库较旧,应尝试使用语法“ ?P<name>”。捕获也可以以数字形式使用:

server {
    server_name   ~^(www\.)?(.+)$;

    location / {
        root   /sites/$2;
    }
}

但是,这种用法应限于简单的情况(如上述情况),因为数字参考很容易被覆盖。

Miscellaneous names

有些服务器名称经过特殊处理。

如果要求处理不是默认值的server块中没有“主机”Headers 字段的请求,则应指定一个空名称:

server {
    listen       80;
    server_name  example.org  www.example.org  "";
    ...
}

如果在server块中未定义server_name,则 nginx 使用空名称作为服务器名称。

Note

在这种情况下,最高 0.8.48 的 nginx 版本将机器的主机名用作服务器名。

如果服务器名称定义为“ $hostname”(0.9.4),则使用计算机的主机名。

如果有人使用 IP 地址而不是服务器名称发出请求,则“主机”请求 Headers 字段将包含 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;
    ...
}

Internationalized names

应在server_name指令中使用 ASCII(Punycode)表示形式来指定国际化域名(IDNs):

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

Optimization

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

首先搜索确切名称哈希表。如果未找到名称,则搜索具有以星号开头的通配符名称的哈希表。如果在此处找不到名称,则搜索带有通配符名称以星号结尾的哈希表。

搜索通配符名称哈希表比搜索精确名称哈希表要慢,因为名称是按域部分搜索的。请注意,特殊的通配符形式“ .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

在这种情况下,指令值应增加到下一个二的幂:

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 根本不会测试服务器名称(并且不会为侦听端口构建哈希表)。但是,有一个 exception。如果服务器名称是带有捕获的正则表达式,则 nginx 必须执行该表达式以获取捕获。

Compatibility

  • 从 0.9.4 开始,支持特殊服务器名称“ $hostname”。

  • 自 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 编辑