nginx Server names

通配符名称

正则表达式名称

混合名称

优化

兼容性

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



当通过名称搜索虚拟服务器时,如果名称与指定的变体(例如通配符名称和正则表达式匹配)中的一个匹配,则将按照下列顺序选择第一匹配变体:

1.确切的名字

2.最长通配符名称以星号开始,例如“*.abc.com

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

4.第一匹配的正则表达式(以配置文件的外观顺序)


通配符的名字通配符名称可能只包含在名称的开始或结束,只有在点边界。名称为“。例如。org”和“W *示例。org”无效。然而,这些名称可以使用正则表达式来指定,例如,“\\ WWW \ + \实例$ \ $”和“。星号可以匹配几个名称部分。“*。例子。org”比赛不仅www.example.org但www.sub.example.org以及。表单中的一个特殊通配符名称可以用来匹配准确的名称“示例”和通配符名称。


通配符

一个通配符可能只在名称的开始或者结束包涵一个*,只在一个边界。

名称 “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 必须以 “~” 字符为起始字符。

server_name  ~^www\d+\.example\.net$;

如果不以 “~” 字符为起始字符,该 server name 将被视为 “准确的主机名” 或者当 server name 包含 “*” 时被视为 “通配主机名” (多数情况是非法通配主机名,因为只有当 “*” 在 server name 的起始或结尾时才合法)。

不要忘记设置 “^” 和 “$” 锚定符对主机名进行界定,这不是 nginx 的配置语法要求,而是为了使正则表达式能正确匹配。

同时也要注意,域名的分隔符 “.” 在正则表达式中应该以 “\” 引用。如果在正则表达式中使用了 “{” 和 “}” 字符,应该将整个正则表达式引用起来,因为花括弧在 nginx 配置中也有特殊意义,引用起来以避免被 nginx 错误解析。例如:

server_name  "~^(?<name>\w\d{1,3}+)\.example\.net$";

如果不引用起来,nginx 会启动失败,并显示如下错误信息:

directive "server_name" is not terminated by ";" in ...

正则表达式的 named capture (使用一个名字对匹配的字符串进行引用)可被视为一个变量,在后面的配置中使用:

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

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

PCRE 库支持 named capture,有如下几种语法:

?<name>        Perl 5.10 compatible syntax, supported since PCRE-7.0
?'name'        Perl 5.10 compatible syntax, supported since PCRE-7.0
?P<name>    Python compatible syntax, supported since PCRE-4.0

可参考:pcre2pattern

 \d     any decimal digit
 \D     any character that is not a decimal digit
 \h     any horizontal white space character
 \H     any character that is not a horizontal white space character
 \s     any white space character
 \S     any character that is not a white space character
 \v     any vertical white space character
 \V     any character that is not a vertical white space character
 \w     any "word" character
 \W     any "non-word" character

如果 nginx 启动失败,并显示如下信息:

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

这表示 PCRE 库太老旧,可尝试使用 “?P<name>” 替代 “?<name>”。

named capture 也能以数字形式使用:

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

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

无论如何,数字形式的使用应尽量简单,因为数字是只是顺序标识,而不是被匹配的字符串的标识,这导致数字引用很容易被覆盖。

混杂主机名


有一些主机名是被特殊对待的。

对于未定义 “Host” 请求首部的请求,如果希望在某个 server 区块中处理这样的请求,应在 server_name 指令的参数中添加 "" 空字符串参数:

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

在《nginx 是如何处理访问请求的》一文中曾经介绍过,如果 server 区块中没有定义 server_name 指令,便如同定义了 server_name ""。

Note:
在 0.8.48 版以前,遇到 server 区块中没有定义 server_name 指令的情况,
会将系统的主机名设置为 server 区块的 server name,而不是自动设置 ""server name。

在 0.9.4 版本,如果设置:server_name $hostname,会将系统的主机名设置为 server name。

如果某个访问使用了 IP 地址 而不是 server name,“Host” 请求首部会包含 IP 地址。对于这样的请求,可使用如下的配置:

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

下面是一个 catch-all server 区块的配置,使用了 “_” 作为 server name:

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

这个 server name 并没有什么特殊之处,它仅是一个无效的域名而已,也可以使用其他类似的名字,如 “--” and “!@#” 。

0.6.25 版以前的 nginx 曾经支持一个特殊的 server name: “*”,这个特殊主机名被错误的解释成一个 catch-all 主机名。但它从未以一个 catch-all 或者 通配主机名工作,它的功能实际上与现在的 server_name_in_redirect 指令的功能相同:server_name_in_redirect

特殊的 server name “*” 现在已经被弃用,应使用 server_name_in_redirect 指令。

要注意的是,使用 server_name 指令无法指定 defalt server 或是 catch-all name,这是 listen 指令的属性,不是 server_name 指令的属性。可参考《nginx 是如何处理访问请求的》。

我们可以定义两个 server,它们都同时监听于 *:80 端口 和 *:8080 端口,将其中一个设置为 *:80 端口的默认 server,将另一个设置为 *:8080 端口的默认 server:

server {
    listen       80;
    listen       8080  default_server;
    server_name  example.net;
    ...
}

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

对主机名的优化


准确的主机名、以 “*” 起始的通配主机名、以 “*” 结尾的通配主机名,这三种主机名被存放在三个 hash table 中。这三个 hash table 是与监听端口绑定的。hash table 的大小在配置阶段被优化,优化的目的是努力降低这些名字在 CPU 缓存中命中失败的几率。关于设置 hash table 的详细讨论请参考:hash

在匹配主机名时,首先查找“准确主机名”的 hash table,如果没有找到,会查找以 “*” 起始的“通配主机名”的 hash table,如果没有仍未找到,会查找以 “*” 结尾的“通配主机名”的 hash table。

对于“通配主机名”的 hash table 的检索会更慢,因为是以主机名的域名部分去检索的。

注意,对于特殊的通配主机名,形如 “.example.org”,这样的主机名是存放在“通配主机名”的 hash table 中,而不是存放在“准确主机名”的 hash table 中。

如果前面都未找到,正则表达式会按写在配置文件中的顺序被测试,因此正则表达式是最慢的方法,并且没有可扩展性。

因为以上这些原因,在可能的情况下最好使用 “准确的主机名”。例如,如果对于 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 context 中调整这个两个参数:

server_names_hash_bucket_size 指令的默认值可能为 32 或 64 或 其他数字,这是根据 CPU 缓存线大小而定的。如果默认值为 32,而且定义了一个 server name 为:“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 的值,设置为大于 server name 总数的值。如果这样设置仍不能让 nginx 正常启动,或者 nginx 启动的时间变得过长,再尝试增加 server_names_hash_bucket_size 的值。

如果一个 server 是某个监听端口唯一的 server,这时 nginx 根本不会去测试 server name,同时也不会为该监听端口构建 hash table。但其中又有一个例外,如果 server name 是正则表达式,而且正则表达式中包含了 captures,这时 nginx 不得不执行该正则表达式以获取 captures。(正则表达式的 capture 是指被圆括号引用的表达式部分,它们所匹配的字符串,可通过名字或数字引用)

兼容性


从 0.9.4 开始支持特殊主机名 “$hostname”

从 0.8.48 开始,如果 server 区块中未定义 server_name 指令,nginx 默认设定空字符串为主机名,如同定义了 server_name ""

从 0.8.25 开始支持在“正则表达式主机名”中使用 named capture 特性

从 0.7.40 开始支持在“正则表达式主机名”中使用 capture 特性

从 0.7.12 开始支持 "" 空字符串主机名

从 0.6.25 开始,支持使用“正则表达式主机名”或者“通配主机名”作为第一个主机名。

从 0.6.7 开始支持“正则表达式主机名”

从 0.6.0 开始支持形如 example.* 的“通配主机名”

从 0.3.18 开始支持形如 .example.org 的特殊“通配主机名”

从 0.1.13 开始支持形如 *.example.org 的“通配主机名”




翻译:http://nginx.org/en/docs/http/server_names.html


  • 7
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: nginx在启动时出现"could not build server_names_hash"的错误,意味着nginx配置文件中的server_names_hash值过小,需要增加server_names_hash的大小。 server_names_hash用于存储nginx配置文件中的server_name指令的哈希表。当有大量的server_name指令时,nginx需要为每个指令分配一个哈希槽位,而哈希槽位的数量由server_names_hash决定。 要解决这个问题,可以按照以下步骤进行操作: 1. 打开nginx的配置文件,一般位于/etc/nginx/nginx.conf或/etc/nginx/conf.d/default.conf。 2. 在http块中找到server_names_hash_bucket_size指令,默认情况下该值为32。这个值表示哈希槽位的数量,可以根据需要适当增大,例如改为64或128。 3. 保存并关闭配置文件后,重新启动nginx服务。 通过增加server_names_hash_bucket_size的值,nginx将能够为更多的server_name指令分配哈希槽位,避免出现"could not build server_names_hash"错误。 需要注意的是,增加server_names_hash_bucket_size值会增加内存占用,因此应根据服务器配置和实际需求来确定合适的值。如果服务器配置资源有限,可以适当调整server_names_hash_bucket_size的值以平衡性能和资源消耗。 ### 回答2: Nginx构建server_names_hash时出现问题,您应该增加server_names_hash的大小。 server_names_hash是Nginx在处理请求时用于快速查找server name的哈希表。它的大小决定了能够处理的域名数量。当服务器上的域名数量超过server_names_hash的大小时,就会出现问题。 要解决这个问题,您需要增加server_names_hash的大小。可以通过修改Nginx的配置文件来完成。 1. 打开Nginx的配置文件,通常位于/etc/nginx/nginx.conf。 2. 在http块中找到server_names_hash_max_size参数。如果没有这个参数,请在server块中添加以下行: server_names_hash_max_size 512; 这里的512是一个示例值,您可以根据您的实际需求进行调整。通常建议设置为比您的域名数量大的一个值。 3. 重新启动Nginx服务以使修改生效。 可以使用以下命令重启Nginx服务: sudo systemctl restart nginx 这样,您就增加了server_names_hash的大小,使其能够处理更多的域名。请确保修改后的值足够大,以适应您的实际场景。 ### 回答3: 当我们在使用Nginx作为服务器时,有时可能会遇到"nginx could not build server_names_hash, you should increase server_names_hash_bucket_size: 32"的错误提示。这个错误主要是由于域名太多,导致了Nginx配置中的server_names_hash值不够大,需要进行调整。 要解决这个问题,我们需要增加server_names_hash_bucket_size的大小。这个值表示服务器名哈希表的桶大小,桶越大可以容纳的域名越多,但同时也会增加内存占用。 首先,我们需要找到Nginx的配置文件,通常是nginx.conf。然后,在http区块中找到或添加"server_names_hash_bucket_size"指令。接下来,我们可以将这个值从默认的32增加到更大的数值,例如64或128。 配置完成后,保存文件并重新启动Nginx服务,这样就完成了server_names_hash_bucket_size的调整。这样Nginx就能够构建整个服务器名哈希表,解决了"nginx could not build server_names_hash"的错误。 需要注意的是,增加server_names_hash_bucket_size值时,也需要考虑服务器的处理能力和内存限制。如果服务器资源有限,建议适当增加这个值,以保证Nginx能够处理更多的域名请求,同时不会导致系统负载过高或内存不足的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值