Nginx設定server_names_hash_max_sizeおよびserver_names_hash_bucket_size


22

Nginxは、誰でも自分のWebサイトを提供するサービスでApacheのリバースプロキシとして使用しています。アカウントの作成時に、システムは2つのエントリを持つドメインの新しいnginx confファイルを作成します。1つはポート80用で、もう1つは443用です。

Restarting nginx: nginx: [emerg] could not build the server_names_hash, 
you should increase either server_names_hash_max_size: 256 
or server_names_hash_bucket_size: 64.

約200のドメインがあり、成長しているため、server_names_hash_maxのサイズを4112に増やす必要があり、これがうまくスケールしないことを懸念しています。これらの構成がどのように機能し、この方法を使用して数千のドメインに成長できるようにするための最適な設定がどのようになるかを理解したいと思っています。

また、そのハッシュサイズでnginxがリロードするのに数秒かかり始めているため、再起動中はシステムが使用できなくなります。

全体的な設定は次のとおりです(Ubuntuサーバー10.10 nginx / 1.0.4で実行):

user www-data;
worker_processes 4;
pid /var/run/nginx.pid;

events {
    worker_connections 4096;
    # multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 300;
    types_hash_max_size 2048;
    # server_tokens off;

    server_names_hash_bucket_size 64;
    # server_name_in_redirect off;
    # server_names_hash_max_size 2056;
    server_names_hash_max_size 4112;
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;
    gzip_disable "msie6";

    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/conf.d/*.conf;

ssl_session_cache shared:SSL:10m;
ssl_ciphers ALL:!kEDH:-ADH:+HIGH:+MEDIUM:-LOW:+SSLv2:-EXP;
}

(暗号の下には、主なサイト構成がいくつかあり、すべてがキャッチされます):

include /etc/user-nginx-confs/*;

server {
listen 80;
server_name .domain.com;
location / {
proxy_pass http://127.0.0.1:8011;
proxy_set_header host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-SystemUse-Header 111;
}
}

server {
listen 443 ssl;
server_name .suredone.com;
ssl_certificate /etc/apache2/sddbx/sdssl/suredone_chained.crt;
ssl_certificate_key /etc/apache2/sddbx/sdssl/suredone.key;
location / {
proxy_pass http://127.0.0.1:44311;
proxy_set_header host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-SystemUse-Header 111;
}
}

server {
listen 80 default_server;
listen 443 default_server ssl;
server_name _;
ssl_certificate /ssl/site_chained.crt;
ssl_certificate_key /ssl/site.key;
return 444;
}

(およびサンプルユーザーconfファイル)

server {
listen 80;
server_name username.domain.com;
location / {
proxy_pass http://127.0.0.1:8011;
proxy_set_header host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-SystemUse-Header 1111;
}
}

server {
listen 443 ssl;
server_name username.domain.com;
ssl_certificate /ssl/site_chained.crt;
ssl_certificate_key /ssl/site.key;
location / {
proxy_pass http://127.0.0.1:44311;
proxy_set_header host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-SystemUse-Header 1111;
}
}

どんな助けと指示も大歓迎です!!

回答:


14

servernginxが提供する名前のリストは、高速ルックアップのためにハッシュテーブルに保存されます。エントリの数を増やすと、ハッシュテーブルのサイズやテーブル内のハッシュバケットの数を増やす必要があります。

セットアップの性質を考えるとserver、テーブルに保存する名前の数を簡単に減らす方法は考えられません。ただし、nginxを「再起動」するのではなく、単に設定を再読み込みすることをお勧めします。例えば:

service nginx reload

それは質問の後半部分にとっては素晴らしいことです、ありがとう。したがって、10000ドメインに到達するために、server_names_hash_max_sizeが20000前後になることを心配する必要がありますか?
jasonspalace

これは、nginxを再起動したときの問題です。私が言ったように、reload代わりに問題を回避するために可能な限り。
マイケルハンプトン

23

私がソースコードから掘り出した技術的な詳細:

  • 一般的な推奨事項は、両方の値をできる限り小さくすることです。
  • nginxが文句を言う場合、文句を言うmax_size限り最初に増加します。数が大きな数(たとえば32769)を超える場合、bucket_size文句を言う限り、プラットフォームのデフォルト値の倍数に増やします。それがもう不平を言わない場合、それが不平をしないmax_size限り戻る。これで、サーバー名のセットに最適なセットアップができました(server_namesの各セットには異なるセットアップが必要な場合があります)。
  • 大きくなるmax_sizeと、より多くのメモリが消費されます(ワーカーまたはサーバーごとに1回、ご存じの場合はコメントしてください)。
  • 大きいbucket_sizeほど、(ドメイン名の検索ごとに)CPUサイクルが多くなり、メインメモリからキャッシュへの転送が多くなります。
  • max_sizeserver_namesの数とは直接関係ありません。サーバーの数が2倍になった場合、max_size衝突を避けるために10倍以上増やす必要があります。それらを回避できない場合は、増やす必要がありますbucket_size
  • bucket_size 次の2の累乗に増加すると言われていますが、ソースコードから、デフォルト値の倍数にするのに十分であると判断します。これにより、キャッシュへの転送が最適になります。
  • ハッシュ配列のオーバーヘッドがあっても、平均的なドメイン名は32バイトに収まるはずです。bucket_size512バイトに増やすと、ハッシュキーが衝突する16個のドメイン名に対応できます。これはあなたが望むものではありません。衝突が発生した場合、直線的に検索します。衝突をできるだけ少なくしたい。
  • あなたが持っている場合はmax_size 10000未満と小さなをbucket_sizenginxのは、ループ内で最適なハッシュサイズを見つけるためにしようとするので、あなたは、長いロード時間に遭遇することができます。
  • max_size10000を超える場合は、文句を言う前に1000回だけループが実行されます。

これは素晴らしい情報です。研究と記事をありがとう。
ワンブル

@brablcたとえば32769に到達した方法に興味があります。現在のヒープサイズはどこで確認できますか?
UHLホスティング

占有メモリはmax_size * bucket_sizeになります(ただし、共有メモリかワーカーごとかはわかりません)。私は8000のサーバー名を持っていて、32769はすでに高すぎると感じました。しかし、多くのメモリがある場合は、もっと高くしたいかもしれません。
brablc

4

nginx.conf内の「server_names_hash_bucket_size」構成を増やします。

私はそれを64から128に変更しました。

問題が解決しました。


2

@マイケル・ハンプトンは彼の答えに絶対に正しい。このハッシュテーブルは再起動または再読み込み中に構築およびコンパイルされ、その後非常に高速に実行されます。このハッシュテーブルは、パフォーマンスを著しく低下させることなく、さらに大きくすることができます。ただし、Cコードの性質上、4096などの2の累乗のサイズを使用することをお勧めします。


どのようなベースで2の累乗、デフォルトの512の倍数で成長するのは正しいですか?
jasonspalace

そのとおり。
フレッシュグラインダー

1

あなたの場合は100%確信はありませんが、X-Forwarded-Protoのproxy_set_headerを2回呼び出していたため、同じ警告が表示されていました:

proxy_set_header X-Forwarded-Proto ...;

これは、proxy_paramsを含めていたために発生していました。

proxy_set_header X-Forwarded-Proto $scheme;

サイトの構成からその行を削除すると、警告は消えました。


1
本当の$$$アドバイス、ありがとう。
sjas

-2

変化する

proxy_set_header X-Forwarded-For $remote_addr;

proxy_set_header X-Real-IP $remote_addr;

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.