この記事では、主に Nginx 仮想サーバーのドメイン名の設定方法を説明します。仮想サーバー名 (サーバー名) は、server_name コマンドで指定します。存在する"
Nginx はリクエストをどのように処理しますか? 「このセクションでは、受信した Request リクエストを 2 つのステップで照合する nginx について説明しました:
1. サーバーを選択
2. 場所を選択
ステップ 1 には、実際には 2 つのステップがあります:
1) . ポートの一致
2).server_name の一致
このセクションでは、nginx が具体的にどのように server_name を一致させるかについて説明します。
server_name コマンド
server_name には 3 つの形式があります:
1. 正確なドメイン名形式 (正確な名前)
2. ワイルドカード (*) 形式
3. 以下の正規表現形式
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$; ... }
ワイルドカード形式は、実際には
forward wildcardと backward wildcard に分かれています (それぞれ 2 番目と 3 番目の例を参照) ワイルドカードを文字列の途中に置くことはできません。
もちろん、ホストが上記の 3 つの形式のうち 1 つ以上に同時に一致する状況もあります。たとえば、ホストが www.example.com の場合、同時に一致する可能性があります。
server_name *.example.com * .com www.example.com www.example.* www.* ~^(.+).example.com$
server_name コマンドパラメータは全部で 6 つあります。
と一致するので、最終的な選択はどれですか?順序があります:
、www.example.comと一致する正確なドメイン名
ワイルドカード*、、*.example.com
ワイルドカード * で終わる最長のドメイン名、www.example.*
、そして最後に正規表現の形式で、設定ファイルに出現する順に一致を試み、最初に一致したものを選択しますドメイン名 ~^(.+).example.com$
ワイルドカード
サーバー名でのワイルドカード * の使用は非常に厳密です。はドメイン名の中央ではなく先頭または末尾にのみ配置でき、「.」で区切る必要があります。 :
*.example.com.example.org
正则表达式
nginx的正则表达式语法使用的是Perl语言(PCRE)的正则语法。基本形式为
server_name ~^www\d+\.example\.net$;
这则表达式需要注意的几点
必须以~开始,没有~符号的要么被视作完全匹配或者通配符匹配
~和正则表达式主体之间没有空格
正则表达式主体通常以^开始以$结束(虽说语法上不一定要求如此,但是从逻辑意义上强烈要求这么做)。
正则表达式中,点号"."必须转义,写作"\.";正则表达式可以不用引号包住,但是,如果其中包含"{"和"}"则必须用双引号包裹
例如:
server_name "~^(?
如果不加引号,nginx便无法正确加载配置文件,并报一个错误:
directive "server_name" is not terminated by ";" in ...
正则表达式使用命名捕获组,例如:
server { server_name ~^(?<myname>.+)\.example\.cn$; root /var/www/hb/$myname; }
PCRE语法支持下面几种捕获语法:
?<name> ?'name' ?P<name>
前面两者是最新的语法,第三种是老的写法。如果nginx报下面错误:
pcre_compile() failed: unrecognized character after (?< in ...
说明,你应该将?
同样,使用普通捕获组也是可以的:
server { server_name ~^(.+)\.example\.cn$; root /var/www/hb/$1; }
当然,普通捕获组要慎用,因为很容易被后面的正则所覆盖。
其他形式
除了两面提到的几种形式,sername_name的指令参数还有可能是其他的几种形式。
如果请求Request没有Host的头部,那么如果想要匹配,可以用空字符串:
server { listen 80; server_name example.org www.example.org ""; ... }
另外,如果在server上下文中,没有定义 server_name,那么nginx使用空字符串作为虚拟机名称。
如果使用IP而不是域名来发起请求,那么Host请求头就是一个IP,此时server_name也可以写成一个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是一个款高性能的web服务器,其设计充满了许多优化的技巧。在使用的时候也不例外,如果我们能对nginx的设计原理有一些了解,我们在配置时就能很好的利用这些设计,从而使得nginx的效率达到最大化。
前面提到,server_name的指令参数匹配有一定的匹配顺序,即最先匹配精确域名形式,然后匹配以通配符*开始的域名,其次匹配以通配符*结束的域名,最后是匹配正则形式。如果前面匹配到了,就会终止继续匹配。
从原理上说,这是因为,nginx会为每个监听的port分别维护精确域名,前向通配符和后项通配符的Hash表。Hash表能在nginx启动的配置阶段得到创建和优化。精确域名的Hash表首先被搜寻,如果找不到,前向通配Hash表会被接着被搜寻,如果也没有找到,那么后向通配Hash表会被搜寻。搜寻通配Hash表要比精确域名Hash表要慢,因为其是按照域名的部分来做搜寻的(比如,*.example.com,会搜寻example和com部分)。
值得注意的是:".example.org"被存在通配Hash表里面,并没有存在精确Hash表里面,因此匹配它是较慢的。
如果以上两种方式都还没有匹配上,那么最后轮到正则形式的指令上场了。正则形式的域名是按照先后顺序一个一个的去匹配的,没有存入任何Hash表,匹配到正确的就结束,因此,这是最慢的形式,没有任何“技巧”可言。
因此,最好的配置方式就是,尽可能使用精确域名,其次是通配符形式的,最后是正则形式。即便是正则形式域名,也要根据实际需要将用的最多的域名尽量前置。这样方可使得nginx的性能达到最大化。
例如:
server { listen 80; server_name example.org www.example.org *.example.org; ... }
这种方式要优于:
server { listen 80; server_name .example.org; ... }
长域名,多域名的情况
在某些情况下,域名会非常的长,nginx不会允许其无限长,默认最大为32。在http上下文中,你可以通过server_names_hash_bucket_size指令来设置,可选参数有32,64(2的N次方)等
例如,如果域名被定义为:"too.long.server.name.example.org",超过32字符,那么会报错:
could not build the server_names_hash,
you should increase server_names_hash_bucket_size: 32
解决方式:
http { server_names_hash_bucket_size 64; ...
在另一些情况下,server_name配置的域名又很多,nginx同样可能报错:
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_names_hash_bucket_size的值(例如将2^N调整到2^(N+1))
http { server_names_hash_max_size:600 server_names_hash_bucket_size 32; ...
如果一个域名是某个监听端口下的唯一域名,那么nginx就不会建立Hash匹配表,也不会有上面介绍的那些匹配流程,然而,如果这个唯一的域名是一个捕获组正则表达式,那么nginx还是去尝试去解析正则表达式以提取这个字段。
相关推荐:
以上がNginx仮想サーバーのドメイン名の設定方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。