ホームページ >バックエンド開発 >PHPチュートリアル >Nginx仮想サーバーのドメイン名の設定方法

Nginx仮想サーバーのドメイン名の設定方法

小云云
小云云オリジナル
2018-03-27 14:32:343197ブラウズ

この記事では、主に 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 つあります。

と一致するので、最終的な選択はどれですか?

順序があります:


  1. www.example.comと一致する正確なドメイン名

  2. ワイルドカード*、、*.example.com

  3. で始まる最長のドメイン名
  4. ワイルドカード * で終わる最長のドメイン名、www.example.*

  5. 、そして最後に正規表現の形式で、設定ファイルに出現する順に一致を試み、最初に一致したものを選択しますドメイン名 ~^(.+).example.com$


は、非常に単純で正確なドメイン名形式を持っています。 次に、server_name のワイルドカード形式と正規表現形式をそれぞれ紹介します。


ワイルドカード

サーバー名でのワイルドカード * の使用は非常に厳密です。

はドメイン名の中央ではなく先頭または末尾にのみ配置でき、「.」で区切る必要があります。 :

*.example.com


www.example.*

以下は違法な形式です:

www.*.example.org

w*.example.org


もちろん、最後の 2 つを実現したい場合は、作成者が反映した目的に正規表現を使用できます。たとえば、上記の 2 つの違法なドメイン名は次のように記述できます:

~^www..+.example.org$


。 ~^w.*.example.org $



もう 1 つの特別な形式は、example.org と *.example.org の両方に一致します。これは

.example.org


正则表达式

nginx的正则表达式语法使用的是Perl语言(PCRE)的正则语法。基本形式为

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

这则表达式需要注意的几点


  • 必须以~开始,没有~符号的要么被视作完全匹配或者通配符匹配

  • ~和正则表达式主体之间没有空格

  • 正则表达式主体通常以^开始以$结束(虽说语法上不一定要求如此,但是从逻辑意义上强烈要求这么做)。

  • 正则表达式中,点号"."必须转义,写作"\.";正则表达式可以不用引号包住,但是,如果其中包含"{"和"}"则必须用双引号包裹

例如:

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

如果不加引号,nginx便无法正确加载配置文件,并报一个错误:

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


正则表达式使用命名捕获组,例如:

server {
    server_name ~^(?<myname>.+)\.example\.cn$;
    root /var/www/hb/$myname;   
}


PCRE语法支持下面几种捕获语法:

?<name>
?&#39;name&#39;
?P<name>

前面两者是最新的语法,第三种是老的写法。如果nginx报下面错误:

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

说明,你应该将?8a11bc632ea32a57b3e3693c7987c420或者?'name'改为较古老的?P8a11bc632ea32a57b3e3693c7987c420写法了。


同样,使用普通捕获组也是可以的:

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还是去尝试去解析正则表达式以提取这个字段。

相关推荐:

php虚拟服务器主机

以上がNginx仮想サーバーのドメイン名の設定方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。