我们使用Nginx作为Apache的反向代理服务,为任何人提供自己的网站。 在创build帐户时,系统为两个条目创build一个新的nginx conf文件,一个用于端口80,另一个用于443.我们注意到在每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,并且担心这个规模不会很好。 我期待了解这些configuration是如何工作的,以及使用这种方法确保我们可以成长为数千个域的最佳设置。
另外,在散列大小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; }
(下面的密码是夫妇主站点configuration和一个捕获所有):
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; } }
任何帮助和方向非常感谢!
nginx提供的server
名称列表存储在一个散列表中,用于快速查找 。 随着您增加条目数量,您必须增加散列表的大小和/或表中散列桶的数量。
考虑到你的设置的性质,我想不出任何方法可以轻松地减less表中存储的server
名称的数量。 不过,我会build议你不要“重新启动”nginx,而只是重新加载它的configuration。 例如:
service nginx reload
只是我从源代码中挖掘出的一些技术细节:
max_size
第一,只要它抱怨。 如果该数字超过某个大数字(例如32769),则只要您的平台发生抱怨,请将您的平台上的bucket_size
增加到默认值的倍数。 如果它不再抱怨,只要不抱怨就减lessmax_size
。 现在,您已经为您的一组服务器名称设置了最好的设置(每组server_name可能需要不同的设置)。 max_size
意味着更多的内存消耗(每个工人或服务器一次,请评论,如果你知道)。 bucket_size
意味着更多的CPU周期(对于每个域名查找)以及从主内存到caching的更多传输。 max_size
与server_names的数量没有直接关系,如果服务器数量增加一倍,则可能需要增加max_size
10倍甚至更多,以避免冲突。 如果你不能避免它们,你必须增加bucket_size
。 bucket_size
是增加到下一个二的幂,从源代码我将判断它应该足以使其成为默认值的倍数,这应该保持传输到caching的最佳状态。 bucket_size
增加到512字节,则可以容纳16个带有相互矛盾的散列键的域名。 这不是你想要的东西,如果发生碰撞线性search 。 你想有尽可能less的碰撞。 max_size
小于10000,并且bucket_size
很小,你可能会遇到很长的加载时间,因为nginx会尝试在循环中find最佳的散列大小。 max_size
大于10000,在执行抱怨之前,只会执行1000次循环。 迈克尔·汉普顿对他的回答是绝对正确的。 这个哈希表是在重启或重载期间构build和编译的,之后运行速度非常快。 我想这个哈希表可以增长很多,而不会降低性能显着。 但是,由于C代码的性质,我build议使用像4096那样的两个幂的大小。
更改
proxy_set_header X-Forwarded-For $remote_addr;
至
proxy_set_header X-Real-IP $remote_addr;