服务器名称

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

服务器名称是使用 server_name 指令定义的 并确定哪个服务器块 用于给定请求。 另请参阅“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$;
    ...
}

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

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

通配符名称

通配符名称只能在名称的开头或结尾包含星号。 并且仅在点边界上。名称 “” 和 “” 无效。 但是,可以使用正则表达式 例如,“” 和 “”. 星号可以匹配多个名称部分。 名称 “” 不仅匹配,而且匹配。www.*.example.orgw*.example.org~^www\..+\.example\.org$~^w.*\.example\.org$*.example.orgwww.example.orgwww.sub.example.org

格式为 “” 的特殊通配符名称可以是 用于匹配确切的名称 “” 和通配符名称 “”。.example.orgexample.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;
    }
}

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

其他名称

有一些服务器名称被特殊对待。

如果需要在没有 “Host” 的情况下处理请求 header 字段,则应指定一个空名称:

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

如果服务器块中没有定义 server_name 然后 nginx 使用空名称作为服务器名称。

nginx 版本直到 0.8.48 都使用计算机的主机名作为服务器名称 在这种情况下。

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

如果有人使用 IP 地址而不是服务器名称发出请求, “Host” 请求标头字段将包含 IP 地址 并且可以使用 IP 地址作为服务器名称来处理请求:

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

在 catch-all 服务器示例中,奇怪的名称 “” 可以 被看到:_

server {
    listen       80  default_server;
    server_name  _;
    return       444;
}

这个名字没有什么特别之处,它只是无数个名字中的一个 的无效域名,且该域名从未与任何真实姓名相交。 其他无效名称,如 “” 和 “” 也可以同样使用。--!@#

nginx 0.6.25 及以下版本支持特殊名称 “” 它被错误地解释为一个包罗万象的名字。 它从未用作 catch-all 或通配符服务器名称。 相反,它提供了现在提供的功能 通过 server_name_in_redirect 指令。 特殊名称 “” 现已弃用 和 server_name_in_redirect 指令。 请注意,无法指定 catch-all 名称或 使用 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) 应使用 ASCII (Punycode) 表示形式指定 在 server_name 指令中:

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

虚拟服务器选择

首先,在默认服务器上下文中创建一个连接。 然后,可以确定服务器名称 在以下请求处理阶段中, 每个都涉及 Server Configuration Selection:

  • 在 SSL 握手期间,根据 SNI 提前

  • 处理请求行后

  • 处理 Header 字段后Host

  • 如果在处理请求行后未确定服务器名称,或者 从 header 字段中, nginx 将使用空名称作为服务器名称。Host

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

优化

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

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

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

按顺序测试正则表达式 ,因此是最慢的方法,并且不可缩放。

由于这些原因,最好尽可能使用确切的名称。 例如,如果请求的服务器名称 是 和 , 显式定义它们更有效:example.orgwww.example.org

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

than 使用简化的形式:

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

如果定义了大量的服务器名称, 或定义了异常长的服务器名称,则 tuning HTTP 级别的 server_names_hash_max_sizeserver_names_hash_bucket_size 指令可能是必需的。 server_names_hash_bucket_size 指令的默认值可能等于 32、64 或其他值 取决于 CPU 缓存行大小。 如果默认值为 32 且服务器名称定义为 “” 然后 nginx 将无法启动并显示错误消息:too.long.server.name.example.org

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 不会测试 服务器名称(并且不会为 listen 端口构建哈希表)。 但是,有一个例外。 如果服务器名称是带有 captures 的正则表达式,则 然后 nginx 必须执行表达式来获取捕获。

兼容性

  • 支持特殊服务器名称 “” 从 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