Nginx 설정 server_names_hash_max_size 및 server_names_hash_bucket_size


22

우리는 Nginx를 자신의 웹 사이트를 제공하는 서비스에서 Apache의 리버스 프록시로 사용하고 있습니다. 계정 생성시 시스템은 포트 80에 대한 항목과 443에 대한 항목 두 개를 사용하여 도메인에 대한 새 nginx conf 파일을 생성합니다. 30 개 정도의 도메인마다 오류가 발생합니다.

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

그것은 질문의 후반부에 좋습니다. 감사합니다. 그렇다면 server_names_hash_max_size가 약 20000 정도가되어 10000 도메인에 도달 할까봐 걱정해야합니까?
jasonspalace

nginx를 다시 시작할 때만 문제가됩니다. 내가 말했듯이, reload대신 문제를 피하기 위해 가능할 때마다.
Michael Hampton

23

소스 코드를 발굴 한 기술적 인 세부 사항은 다음과 같습니다.

  • 일반적으로 두 값을 모두 작게 유지하는 것이 좋습니다.
  • nginx가 불평하는 경우 불평하는 한 max_size먼저 증가 합니다. 숫자가 큰 숫자 (예 : 32769)를 초과하는 경우, bucket_size불만이있는 한 플랫폼에서 기본값의 배수로 증가 하십시오. 더 이상 불만이 없으면 불만이없는 max_size한 줄이십시오. 이제 서버 이름 세트에 가장 적합한 설정을 갖습니다 (각 server_name 세트마다 다른 설정이 필요할 수 있음).
  • 더 클수록 더 max_size많은 메모리가 소비됨을 의미합니다 (작업자 또는 서버 당 한 번, 알고있는 경우 의견을 말하십시오).
  • 클수록 더 bucket_size많은 CPU주기 (모든 도메인 이름 조회에 대해)와 주 메모리에서 캐시로의 더 많은 전송이 필요합니다.
  • max_sizeserver_names 수와 직접 관련이 없으며, 서버 수가 두 배가되면 max_size충돌을 피하기 위해 10 배 이상 증가해야 할 수도 있습니다 . 당신이 그들을 피할 수 없다면, 당신은 증가해야합니다 bucket_size.
  • bucket_size 소스 코드에서 2의 다음 제곱으로 증가한다고합니다. 소스 코드에서 기본값의 배수로 충분해야한다고 판단하면 전송을 캐시로 최적으로 유지해야합니다.
  • 해시 배열 오버 헤드가 발생하더라도 평균 도메인 이름은 32 바이트에 맞아야합니다. bucket_size512 바이트로 늘리면 충돌하는 해시 키가 포함 된 16 개의 도메인 이름을 사용할 수 있습니다. 충돌이 발생 하면 선형으로 검색 합니다. 가능한 적은 충돌을 원합니다.
  • 당신이있는 경우 max_size 10000 이하 소형을 bucket_sizenginx를 루프에서 최적의 해시 크기를 찾으려고 때문에, 당신은 긴 로딩 시간에 걸쳐 올 수 있습니다.
  • 당신이있는 경우 max_size10000보다 큰, 그것은 불평 것 전에 "전용"1000 루프 수행이있을 것이다.

이것은 훌륭한 정보입니다; 연구 및 작성에 감사드립니다.
womble

@ brablc 예를 들어 32769에 어떻게 도달했는지 궁금합니다. 현재 힙 크기를 어디에서 볼 수 있습니까?
Uhl Hosting

점유 된 메모리는 max_size * bucket_size입니다 (그러나 공유 또는 작업자 당인지는 알 수 없습니다). 서버 이름이 8000이고 32769가 이미 너무 높았습니다. 그러나 많은 메모리가 있다면 더 높아지고 싶을 것입니다.
brablc

4

nginx.conf에서 "server_names_hash_bucket_size"구성을 늘리십시오.

나는 64를 가지고 128로 변경했습니다.

문제 해결됨.


2

@Michael Hampton은 그의 대답에 절대적으로 옳습니다. 이 해시 테이블은 재시작 또는 재로드 중에 구성 및 컴파일 된 후 매우 빠르게 실행됩니다. 이 해시 테이블은 성능을 현저하게 저하시키지 않으면 서 훨씬 더 커질 수 있다고 생각합니다. 그러나 C 코드의 특성으로 인해 4096과 같이 2의 거듭 제곱 크기를 사용하는 것이 좋습니다.


어떤 기초를 가진 2의 거듭 제곱, 기본값 512의 배수로 자라는 것이 맞습니까?
jasonspalace

네 그럼요.
Fleshgrinder

1

귀하의 경우 100 % 확신 할 수는 없지만 X-Forwarded-Proto에 대해 proxy_set_header를 두 번 호출했기 때문에 동일한 경고가 발생했습니다.

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.