Nginx Configuração server_names_hash_max_size e server_names_hash_bucket_size

14

Estamos usando o Nginx como um proxy reverso do Apache em um serviço que fornece a qualquer um o seu próprio site. Na criação da conta, o sistema cria um novo arquivo nginx conf para o domínio com duas entradas, uma para a porta 80 e outra para o 443. Estamos percebendo que a cada 30 ou mais domínios, obtemos o erro:

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.

Com cerca de 200 domínios e crescendo, tivemos que aumentar o tamanho de server_names_hash_max para 4112 e estamos preocupados que isso não vai escalar bem. Estou procurando entender como essas configurações funcionam e quais seriam as configurações ideais para garantir que possamos crescer para milhares de domínios usando esse método.

Além disso, nesse tamanho de hash, o nginx está começando a demorar segundos para recarregar, o que está fazendo com que o sistema fique indisponível enquanto é reiniciado.

Aqui estão as configurações gerais (rodando no servidor 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;
}

(Abaixo das cifras estão algumas configurações do site principal e uma captura de todos):

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

(e um arquivo conf de usuário de amostra)

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

Qualquer ajuda e direção é muito apreciada !!

    
por jasonspalace 22.08.2012 / 01:05

6 respostas

12

A lista de server nomes que o nginx atende é armazenado em uma tabela de hash para pesquisa rápida . À medida que você aumenta o número de entradas, você precisa aumentar o tamanho da tabela de hash e / ou o número de hash de hash na tabela.

Dada a natureza da sua configuração, não consigo pensar em nenhuma maneira de reduzir facilmente o número de server nomes que você está armazenando na tabela. Vou sugerir, no entanto, que você não "reinicie" o nginx, mas simplesmente que ele recarregue sua configuração. Por exemplo:

service nginx reload
    
por 22.08.2012 / 01:14
14

Apenas alguns detalhes técnicos que eu criei formam o código-fonte:

  • A recomendação geral seria manter os dois valores o menor possível.
  • Se reclamações do nginx aumentam max_size primeiro, desde que se queixem. Se o número exceder um número grande (32769, por exemplo), aumente bucket_size para múltiplos de valor padrão em sua plataforma, desde que se queixem. Se não reclamar mais, diminua max_size desde que não reclame. Agora você tem a melhor configuração para o seu conjunto de nomes de servidores (cada conjunto de nomes_do_servidor pode precisar de configuração diferente).
  • Maior max_size significa mais memória consumida (uma vez por funcionário ou servidor, por favor, comente se você souber).
  • Maior bucket_size significa mais ciclos de CPU (para cada consulta de nome de domínio) e mais transferências da memória principal para o cache.
  • max_size não está relacionado ao número de nomes_do_servidor diretamente, se o número de servidores duplicar, talvez seja necessário aumentar max_size 10 vezes ou até mais para evitar colisões. Se você não pode evitá-los, você tem que aumentar bucket_size .
  • Diz-se que bucket_size é aumentado para a próxima potência de dois, a partir do código-fonte que eu julgaria que deveria ser suficiente para torná-lo múltiplo do valor padrão, isso deve manter as transferências em cache ideais.
  • O nome de domínio médio deve caber em 32 bytes, mesmo com sobrecarga de matriz de hash. Se você aumentar bucket_size para 512 bytes, ele acomodaria 16 nomes de domínio com chave hash de colisão. Isso não é algo que você quer, se a colisão acontecer ele procura linearmente . Você quer ter menos colisões possíveis.
  • Se você tem max_size menor que 10000 e pequena bucket_size , você pode se deparar com um longo tempo de carregamento porque o nginx tentaria encontrar o tamanho de hash ideal em um loop.
  • Se você tiver max_size maior que 10000, haverá "apenas" 1000 loops realizados antes de reclamar.
por 28.06.2016 / 17:08
1

@ Michael Hampton está absolutamente certo com a sua resposta. Esta tabela de hash é construída e compilada durante a reinicialização ou recarregamento e depois é executada muito rapidamente. Eu acho que esta tabela de hash poderia crescer muito mais sem degradar o desempenho perceptível. Mas eu sugiro usar um tamanho que é o poder de dois, como 4096, devido à natureza do código C.

    
por 22.08.2012 / 11:05
1

Aumente a configuração "server_names_hash_bucket_size" dentro do seu nginx.conf.

Eu tinha 64 e mudei para 128.

Problema resolvido.

    
por 10.01.2018 / 17:06
0

Não tenho 100% de certeza no seu caso, mas recebi o mesmo aviso porque estava chamando proxy_set_header para o X-Forwarded-Proto duas vezes:

proxy_set_header X-Forwarded-Proto ...;

Isso estava acontecendo porque eu estava incluindo proxy_params e contém essa linha entre outros:

proxy_set_header X-Forwarded-Proto $scheme;

Remover essa linha da configuração do meu site fez com que o aviso desaparecesse.

    
por 03.09.2018 / 23:36
-2

Alterar

proxy_set_header X-Forwarded-For $remote_addr;

para

proxy_set_header X-Real-IP $remote_addr;

    
por 02.03.2017 / 10:02

Tags