Nginx Cài đặt server_names_hash_max_size và server_names_hash_bucket_size


22

Chúng tôi đang sử dụng Nginx làm proxy ngược cho Apache trong một dịch vụ cung cấp cho bất kỳ ai trang web của riêng họ. Khi tạo tài khoản, hệ thống tạo một tệp nginx conf mới cho tên miền có hai mục nhập, một cho cổng 80, một cho 443. Chúng tôi nhận thấy rằng cứ sau 30 tên miền, chúng tôi sẽ gặp lỗi:

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.

Với khoảng 200 tên miền và đang phát triển, chúng tôi đã phải tăng kích thước server_names_hash_max lên 4112 và lo ngại điều này sẽ không có quy mô tốt. Tôi đang tìm hiểu cách thức các cấu hình này hoạt động và các cài đặt tối ưu sẽ là gì để đảm bảo chúng tôi có thể phát triển lên hàng nghìn tên miền bằng phương pháp này.

Ngoài ra, tại kích thước băm đó nginx đang bắt đầu mất vài giây để tải lại, điều này khiến hệ thống không khả dụng trong khi khởi động lại.

Dưới đây là các cài đặt tổng thể (chạy trên máy chủ 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;
}

(Bên dưới các mật mã là một vài cấu hình trang web chính và bắt tất cả):

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

(Và một tệp conf người dùng mẫu)

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

Bất kỳ trợ giúp và hướng được đánh giá rất cao !!

Câu trả lời:


14

Danh sách các servertên mà nginx phục vụ được lưu trữ trong bảng băm để tra cứu nhanh . Khi bạn tăng số lượng mục nhập, bạn phải tăng kích thước của bảng băm và / hoặc số lượng hàm băm trong bảng.

Do tính chất của thiết lập của bạn, tôi không thể nghĩ ra bất kỳ cách nào để bạn dễ dàng giảm số lượng servertên bạn đang lưu trữ trong bảng. Tuy nhiên, tôi sẽ đề nghị bạn không "khởi động lại" nginx, mà chỉ đơn giản là để nó tải lại cấu hình của nó. Ví dụ:

service nginx reload

Đó là điều tuyệt vời cho phần sau của câu hỏi, cảm ơn. Vì vậy, tôi có nên lo ngại rằng server_names_hash_max_size sẽ ở đâu đó khoảng 20000 để có được 10000 tên miền không?
jasonspalace

Đó chỉ là một vấn đề khi bạn khởi động lại nginx. Như tôi đã nói, reloadthay vào đó bất cứ khi nào có thể để tránh vấn đề.
Michael Hampton

23

Chỉ cần một số chi tiết kỹ thuật mà tôi đã đào mã nguồn:

  • Khuyến nghị chung là giữ cả hai giá trị càng nhỏ càng tốt.
  • Nếu nginx phàn nàn tăng max_sizeđầu tiên miễn là nó phàn nàn. Nếu số lượng vượt quá một số lớn (ví dụ 32769), hãy tăng bucket_sizelên nhiều giá trị mặc định trên nền tảng của bạn miễn là nó phàn nàn. Nếu nó không phàn nàn nữa, hãy giảm xuống max_sizemiễn là nó không phàn nàn. Bây giờ bạn đã có thiết lập tốt nhất cho bộ tên máy chủ của mình (mỗi bộ server_names có thể cần thiết lập khác nhau).
  • Lớn hơn max_sizecó nghĩa là bộ nhớ tiêu thụ nhiều hơn (một lần cho mỗi công nhân hoặc máy chủ, vui lòng bình luận nếu bạn biết).
  • Lớn hơn bucket_sizecó nghĩa là nhiều chu kỳ CPU hơn (cho mỗi lần tra cứu tên miền) và chuyển nhiều hơn từ bộ nhớ chính sang bộ đệm.
  • max_sizekhông liên quan trực tiếp đến số lượng server_names, nếu số lượng máy chủ tăng gấp đôi, bạn có thể cần tăng max_sizegấp 10 lần hoặc thậm chí nhiều hơn để tránh va chạm. Nếu bạn không thể tránh chúng, bạn phải tăng lên bucket_size.
  • bucket_size được cho là tăng lên sức mạnh tiếp theo của hai, từ mã nguồn tôi sẽ đánh giá nó là đủ để làm cho nó có nhiều giá trị mặc định, điều này sẽ giữ cho việc chuyển sang bộ nhớ cache tối ưu.
  • Tên miền trung bình phải phù hợp với 32 byte ngay cả với chi phí mảng băm. Nếu bạn tăng bucket_sizelên 512 byte, nó sẽ chứa 16 tên miền với khóa băm va chạm. Đây không phải là thứ bạn muốn, nếu va chạm xảy ra, nó sẽ tìm kiếm tuyến tính . Bạn muốn có càng ít va chạm càng tốt.
  • Nếu bạn có max_size ít hơn 10000 và nhỏ bucket_size, bạn có thể gặp thời gian tải lâu vì nginx sẽ cố gắng tìm kích thước băm tối ưu trong một vòng lặp.
  • Nếu bạn có max_sizelớn hơn 10000, sẽ có "1000" vòng lặp được thực hiện trước khi nó khiếu nại.

Đây là thông tin tuyệt vời; cảm ơn vì đã nghiên cứu và viết lên
womble

@brablc Tôi tò mò làm thế nào bạn có đến 32769 chẳng hạn. Nơi nào người ta có thể thấy những gì kích thước heap hiện tại?
Uhl Hosting

Bộ nhớ bị chiếm dụng sẽ là max_size * buck_size (nhưng tôi không biết nó được chia sẻ hay mỗi nhân viên). Tôi đã có 8000 tên máy chủ và 32769 cảm thấy đã quá cao. Nhưng nếu bạn có nhiều bộ nhớ, bạn có thể muốn tăng cao hơn.
brablc

4

Tăng cấu hình "server_names_hash_bucket_size" bên trong nginx.conf của bạn.

Tôi đã có nó 64 và thay đổi thành 128.

Vấn đề được giải quyết.


2

@Michael Hampton hoàn toàn đúng với câu trả lời của mình. Bảng băm này được xây dựng và biên dịch trong quá trình khởi động lại hoặc tải lại và sau đó nó chạy rất nhanh. Tôi đoán bảng băm này có thể phát triển hơn rất nhiều mà không làm giảm hiệu suất đáng chú ý. Nhưng tôi khuyên bạn nên sử dụng kích thước có sức mạnh bằng hai, như 4096, do bản chất của mã C.


Sức mạnh của hai với cơ sở nào, Có đúng không khi tăng theo bội số của mặc định 512?
jasonspalace

Phải, chắc chắn rồi.
Xác thịt

1

Tôi không chắc chắn 100% trong trường hợp của bạn, nhưng tôi đã nhận được cảnh báo tương tự vì tôi đã gọi proxy_set_header cho X-Forwarded-Proto hai lần:

proxy_set_header X-Forwarded-Proto ...;

Điều này đã xảy ra bởi vì tôi đã bao gồm proxy_params và nó chứa dòng này trong số những người khác:

proxy_set_header X-Forwarded-Proto $scheme;

Việc xóa dòng đó khỏi cấu hình trang web của tôi khiến cảnh báo biến mất.


1
tư vấn $$$ thực sự, cảm ơn.
sjas

-2

Thay đổi

proxy_set_header X-Forwarded-For $remote_addr;

đến

proxy_set_header X-Real-IP $remote_addr;

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.