本文共 4619 字,大约阅读时间需要 15 分钟。
说明:“Nginx烂笔头”系列Blog是自己对Nginx官方文档的的翻译,用作阅读笔记便于日后查阅的成分居多,无关重要内容会删减,也可能会加入自己的理解。囿于个人水平,一些专业的名称翻译不会太准确,推荐查看。翻译内容如果有错误,欢迎指正。
本文翻译自Nginx官网网页文档。
本文主要讲述了server指令块中server_name
指令的使用事项,主要为server_name
指令的精确命名、通配符命名、正则表达式命名和其他命名方法。
服务名称是使用server_name
指令定义的并决定了一个请求使用哪一个服务块来处理。可以参考。服务名可以使用一个确切的、通配符或者正则表达式来命名。
#确切地指定一个名称server { listen 80; server_name example.org www.example.org; ...}#通配符命名server { listen 80; server_name *.example.org; ...}#通配符命名2server { listen 80; server_name mail.*; ...}#正则表达式命名server { listen 80; server_name ~^(?.+)\.example\.net$; ...}
当nginx通过名称来搜索虚拟服务时,如果一个名称匹配到多个指定的服务块,例如,同时匹配上了通配符和正则表达式的,那nginx会按照下面优先级来选择最先匹配到的server块来处理这个请求:
1. 准确的名称 2. 以号开始最长的通配符命名 3. 以号结束最长的通配符命名 4. 第一个匹配到的正则表达式命名(按照在配置文件出现的先后顺序)
一个通配符名称可以在开始或结束包含号,也可以在“.”号之间。名称www.*.example.org```和```w*.example.org
都是正确的命名 。然而,这些名称也可以使用正则表达式来命名,例如,~^www\..+\.example\.org$
和~^w.*\.example\.org$
。一个号可以同时匹配上server name以“.”号分割的不同部分。*.example.org
可以同时匹配上www.example.org
和www.sub.example.org
这两个服务名称。
A special wildcard name in the form “.example.org” can be used to match both the exact name “” and the wildcard name “*.example.org”.
nginx使用的正则表达式和Perl语言使的(PCRE)是兼容的,server_name的参数必须以~
开头:
server_name ~^www\d+\.example\.net$;
否则,nginx会把参数视作一个准确的名称,如果表达式包含一个*号,则会被视作一个通配符命名方式。不要忘记^
和$
符号。他们在语法上不是必须的,但是在(nginx)逻辑上是必须的。同时注意,域名的“."符号需要使用反斜线进行转义。表达式里面如果有“{”和“}”需要用括号扩起来:
server_name "~^(?\w\d{1,3}+)\.example\.net$";
否则,nginx会启动失败并抛出下面的错误信息
directive “server_name” is not terminated by “;” in …
正则表达式中的字段可以被捕获成一个变量,在接下来可以使用:
server { server_name ~^(www\.)?(?.+)$; location / { root /sites/$domain; }}
PCRE库使在不同版本对变量捕获的语法支持:
如果ngins启动失败,并出现下面的错误信息:
pcre_compile() failed: unrecognized character after (?< in …
这说明PCRE库版本太旧,应该使用?P 语法。
捕获也可以使用数字的格式:server { server_name ~^(www\.)?(.+)$; location / { root /sites/$2; }}
但是,这种用法应该被限制在简单的例子中使用,比如上面的,因为数值应用容易被重写覆盖。
有一些其他的命名方式被特殊对待。
在一个不是默认server块指令中需要处理不带“Host”请求头的请求,需要加上空名称:
server { listen 80; server_name example.org www.example.org ""; ...}
如果server指令块种没有指定server_name指令,nginx回默认用空字符串做server_name。
nginx在0.8.48前都是用机器的主机名作为服务名。
如果服务名被定义为"$hostname"(0.9.4),就回使用机器的主机名。
如果请求是使用ip的也可以配置在服务名种,nginx也会处理:
server { listen 80; server_name example.org www.example.org "" 192.168.1.1 ; ... }
在下面的例子中会处理所有host的请求,你可以看到有一个“_”字符串:
server { listen 80 default_server; server_name _; return 444;}
名称没有特别之处,都是不合法的host之一。其他类似的不合法字符,如:“!@#”也可以使用。
nginx在0.6.25之前都支持特殊名称“*”,通常会被错误地认为是用来处理所有host请求地特殊名字。使用“*”从来不会起到处理所有host地作用,或者类似一个通配符名称。相反地,它提供了server_name_in_redirect
指令地功能。现在,“*”已经被弃用,应该使用server_name_in_redirect
指令来代替。需要注意的是,使用server_name
指令不能配置一个默认的server或者处理所有请求的server。可以查看.只能指定默认的host是默认由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表示:
server { listen 80; server_name xn--e1afmkfd.xn--80akhbyknj4f; # пример.испытание ...}
准确名称,以“*”号开头或结尾的通配符名称被存储在和端口绑定的3个哈希表中。哈希表的大小是可以使用配置文件来优化的,以减少CPU的未命中缓存时间来加快检索。具体可以查看此.
三张哈希表的优先顺序是:准确名称哈希表,“*号”开头的哈希表,“*号”结束的哈希表。
搜索通配符名称要比准确的名称慢因为是根据域名不分来检索的。需要注意的是特殊通配符“.example.com"是保存在通配符哈希表中的而不是准确名称哈希表中。
正则表达式会被顺序的匹配,所以是最慢的一个而且无法伸缩。
所以,如果可以最好使用准确的名称。例如:,最有效率的配置是直接配置:
server { listen 80; server_name example.org www.example.org *.example.org; ...}
比这样简单的配置要高效:
server { listen 80; server_name .example.org; ...}
如果配置了很多server name或者很长的server name,那有必要通过http指令块中的server_name_hash_max_size
和server_names_hash_bucket_size
指令来调整哈希表的大小。server_names_hash_bucket_size
默认值是32或者64,取决于CPU的缓存页大小。如果值是32,但是server name过长,会报以下的错误:
could not build the server_names_hash,
you should increase server_names_hash_bucket_size: 32
此时,需要修改server_names_hash_bucket_size
,数值需为2的N次幂:
http { server_names_hash_bucket_size 64; ... }
如果过多server name会报下面的异常:
could not build the server_names_hash,you should increase either server_names_hash_max_size: 512or server_names_hash_bucket_size: 32
上面这种情况,首先尝试设置server_name_hash_max_size
的大小。
如果server只监听了一个端口,nginx完全就不会匹配server name了,也就不会创建三张哈希表。有个例外就是,当server name是正则表达式的时候还是会去匹配server name了。
转载地址:http://xtsni.baihongyu.com/