Nginx Mengatur server_names_hash_max_size dan server_names_hash_bucket_size


22

Kami menggunakan Nginx sebagai proxy terbalik ke Apache dalam layanan yang memberikan situs web kepada siapa pun. Pada pembuatan akun, sistem membuat file conf nginx baru untuk domain dengan dua entri, satu untuk port 80, yang lain untuk 443. Kami memperhatikan bahwa pada setiap 30 atau lebih domain, kami mendapatkan kesalahan:

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.

Dengan sekitar 200 domain dan terus bertambah, kami harus menaikkan ukuran server_names_hash_max menjadi 4112 dan khawatir ini tidak akan skala dengan baik. Saya ingin memahami cara kerja konfigurasi ini dan pengaturan optimal apa yang akan memastikan kami dapat tumbuh hingga ribuan domain menggunakan metode ini.

Juga, pada ukuran hash nginx mulai mengambil detik untuk memuat ulang yang menyebabkan sistem tidak tersedia saat restart.

Berikut adalah pengaturan keseluruhan (berjalan pada server 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;
}

(Di bawah cipher ada pasangan konfigurasi situs utama dan tangkapan semua):

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;
}

(Dan file conf pengguna sampel)

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;
}
}

Setiap bantuan dan arahan sangat dihargai !!

Jawaban:


14

Daftar servernama yang dilayani nginx disimpan dalam tabel hash untuk pencarian cepat . Saat Anda menambah jumlah entri, Anda harus menambah ukuran tabel hash dan / atau jumlah ember hash di tabel.

Mengingat sifat pengaturan Anda, saya tidak bisa memikirkan cara apa pun untuk Anda dengan mudah mengurangi jumlah servernama yang Anda simpan di tabel. Saya akan menyarankan, bahwa Anda tidak "me-restart" nginx, tetapi cukup memuat ulang konfigurasinya. Contohnya:

service nginx reload

Itu bagus untuk bagian terakhir dari pertanyaan, terima kasih. Jadi haruskah saya khawatir bahwa server_names_hash_max_size akan berada di sekitar 20000 untuk mencapai 10.000 domain?
jasonpalace

Ini hanya masalah ketika Anda me-restart nginx. Seperti yang saya katakan, reloadalih-alih sedapat mungkin hindari masalah.
Michael Hampton

23

Hanya beberapa detail teknis yang saya gali dari kode sumber:

  • Rekomendasi umum adalah untuk menjaga kedua nilai sekecil mungkin.
  • Jika nginx mengeluh meningkat max_sizepertama selama itu mengeluh. Jika angka tersebut melebihi angka besar (misalnya 32769), naikkan bucket_sizeke kelipatan nilai default pada platform Anda asalkan komplain. Jika tidak mengeluh lagi, kurangi max_sizekembali selama tidak mengeluh. Sekarang Anda memiliki setup terbaik untuk set nama server Anda (setiap set nama server mungkin memerlukan setup berbeda).
  • Lebih besar max_sizeberarti lebih banyak memori yang dikonsumsi (satu kali per pekerja atau server, beri komentar jika Anda tahu).
  • Lebih besar bucket_sizeberarti lebih banyak siklus CPU (untuk setiap pencarian nama domain) dan lebih banyak transfer dari memori utama ke cache.
  • max_sizetidak terkait dengan jumlah nama server secara langsung, jika jumlah server berlipat ganda, Anda mungkin perlu menambah max_size10 kali atau bahkan lebih untuk menghindari tabrakan. Jika Anda tidak dapat menghindarinya, Anda harus meningkat bucket_size.
  • bucket_size dikatakan meningkat ke kekuatan dua berikutnya, dari kode sumber saya akan menilai itu harus cukup untuk membuatnya kelipatan dari nilai default, ini harus menjaga transfer ke cache optimal.
  • Nama domain rata-rata harus masuk ke dalam 32 byte bahkan dengan overhead array hash. Jika Anda meningkatkan bucket_sizemenjadi 512 byte, itu akan mengakomodasi 16 nama domain dengan kunci hash bertabrakan. Ini bukan sesuatu yang Anda inginkan, jika terjadi tabrakan pencarian itu secara linear . Anda ingin tabrakan sesedikit mungkin.
  • Jika Anda memiliki max_size kurang dari 10.000 dan kecil bucket_size, Anda dapat menemukan waktu pemuatan yang lama karena nginx akan mencoba menemukan ukuran hash yang optimal dalam satu lingkaran.
  • Jika Anda memiliki max_sizelebih dari 10.000, akan ada "hanya" 1000 loop dilakukan sebelum mengeluh.

Ini adalah info hebat; terima kasih untuk penelitian dan penulisan.
womble

@ brablc Saya ingin tahu bagaimana Anda bisa ke 32769 misalnya. Di mana orang bisa melihat apa ukuran tumpukan saat ini?
Uhl Hosting

Memori yang ditempati akan menjadi max_size * bucket_size (tapi saya tidak tahu apakah itu dibagikan atau per pekerja). Saya memiliki 8000 nama server dan 32769 terasa sudah terlalu tinggi. Tetapi jika Anda memiliki banyak memori, Anda mungkin ingin lebih tinggi.
brablc

4

Tingkatkan konfigurasi "server_names_hash_bucket_size" di dalam nginx.conf Anda.

Saya memilikinya 64 dan berubah menjadi 128.

Masalah terpecahkan.


2

@Michael Hampton benar dengan jawabannya. Tabel hash ini dibangun dan dikompilasi selama restart atau memuat kembali dan setelah itu berjalan sangat cepat. Saya kira tabel hash ini bisa tumbuh lebih banyak tanpa menurunkan kinerja yang terlihat. Tapi saya sarankan menggunakan ukuran yang kekuatan dua, seperti 4096, karena sifat kode C.


Kekuatan dua dengan basis apa, Apakah benar untuk tumbuh dalam kelipatan dari standar 512?
jasonpalace

Ya, tentu saja.
Fleshgrinder

1

Saya tidak 100% yakin dalam kasus Anda, tetapi saya mendapatkan peringatan yang sama karena saya menelepon proxy_set_header untuk X-Forwarded-Proto dua kali:

proxy_set_header X-Forwarded-Proto ...;

Ini terjadi karena saya termasuk proxy_params, dan ini berisi baris ini antara lain:

proxy_set_header X-Forwarded-Proto $scheme;

Menghapus baris itu dari konfigurasi situs saya membuat peringatan hilang.


1
saran $$$ asli, terima kasih.
sjas

-2

Perubahan

proxy_set_header X-Forwarded-For $remote_addr;

untuk

proxy_set_header X-Real-IP $remote_addr;

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.