2012-09-02 43 views
17

Trong 3 tuần qua chúng tôi đã kiểm tra Nginx là cân bằng tải. Hiện tại, chúng tôi không thể xử lý hơn 1000 kết nối hoạt động req/sec và 18K. Khi chúng tôi nhận được các con số trên, Nginx bắt đầu treo và trả về mã hết thời gian chờ. Cách duy nhất để nhận phản hồi là giảm số lượng kết nối đáng kể.Nginx Cân bằng tải lưu lượng cao

Tôi phải lưu ý rằng các máy chủ của tôi có thể và xử lý lưu lượng truy cập này hàng ngày và hiện tại chúng tôi sử dụng cân bằng DNS vòng rubin đơn giản.

Chúng tôi đang sử dụng một máy chủ chuyên dụng với HW sau: CPU

  • Intel Xeon E5620
  • 16GB RAM
  • 2T SATA HDD
  • 1Gb/s kết nối
  • Hệ điều hành: CentOS 5.8

Chúng tôi cần tải cân bằng 7 máy chủ quay lại chạy Tomca t6 và xử lý hơn 2000 lần/giây vào thời gian nhìn trộm, xử lý các yêu cầu HTTP và HTTPS.

Trong khi chạy mức tiêu thụ cpu của Nginx là khoảng 15% và RAM được sử dụng là khoảng 100MB.

Câu hỏi của tôi là:

  1. Có bất kỳ một cố gắng để cân bằng tải loại này lưu lượng sử dụng nginx?
  2. Bạn có nghĩ nginx có thể xử lý lưu lượng truy cập như vậy không?
  3. Bạn có biết bất kỳ điều gì có thể gây ra sự cố không?
  4. Tôi có thiếu gì đó trên cấu hình của mình không?

Dưới đây là file cấu hình của tôi:

nginx.conf:

user nginx; 
worker_processes 10; 

worker_rlimit_nofile 200000; 

error_log /var/log/nginx/error.log warn; 
pid  /var/run/nginx.pid; 


events { 
    worker_connections 10000; 
    use epoll; 
    multi_accept on; 
} 


http { 
    include  /etc/nginx/mime.types; 
    default_type application/octet-stream; 

    log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 
         '$status $body_bytes_sent "$http_referer" ' 
         '"$http_user_agent" "$http_x_forwarded_for"'; 

    #access_log /var/log/nginx/access.log main; 
    access_log off; 

    sendfile  on; 
    tcp_nopush  on; 

    keepalive_timeout 65; 
    reset_timedout_connection on; 

    gzip on; 
    gzip_comp_level 1; 
    include /etc/nginx/conf.d/*.conf; 
} 

servers.conf:

#Set the upstream (servers to load balance) 
#HTTP stream 
upstream adsbar { 
    least_conn; 
    server xx.xx.xx.34 max_fails=2 fail_timeout=15s; 
    server xx.xx.xx.36 max_fails=2 fail_timeout=15s; 
    server xx.xx.xx.37 max_fails=2 fail_timeout=15s; 
    server xx.xx.xx.39 max_fails=2 fail_timeout=15s; 
    server xx.xx.xx.40 max_fails=2 fail_timeout=15s; 
    server xx.xx.xx.42 max_fails=2 fail_timeout=15s; 
    server xx.xx.xx.43 max_fails=2 fail_timeout=15s; 
}  

#HTTPS stream 
upstream adsbar-ssl { 
    least_conn; 
    server xx.xx.xx.34:443 max_fails=2 fail_timeout=15s; 
    server xx.xx.xx.36:443 max_fails=2 fail_timeout=15s; 
    server xx.xx.xx.37:443 max_fails=2 fail_timeout=15s; 
    server xx.xx.xx.39:443 max_fails=2 fail_timeout=15s; 
    server xx.xx.xx.40:443 max_fails=2 fail_timeout=15s; 
    server xx.xx.xx.42:443 max_fails=2 fail_timeout=15s; 
    server xx.xx.xx.43:443 max_fails=2 fail_timeout=15s; 
} 

#HTTP 
server { 
    listen xxx.xxx.xxx.xxx:8080; 
    server_name www.mycompany.com; 
    location/{ 
     proxy_set_header Host $host; 
     # So the original HTTP Host header is preserved 
     proxy_set_header X-Real-IP $remote_addr; 
     # The IP address of the client (which might be a proxy itself) 
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
     proxy_pass http://adsbar; 
    } 
} 

#HTTPS 
server { 
    listen xxx.xxx.xxx.xxx:8443; 
    server_name www.mycompany.com; 
    ssl on; 
    ssl_certificate /etc/pki/tls/certs/mycompany.crt; 
    # Path to an SSL certificate; 
    ssl_certificate_key /etc/pki/tls/private/mycompany.key; 
    # Path to the key for the SSL certificate; 
    location/{ 
     proxy_set_header Host $host; 
     # So the original HTTP Host header is preserved 
     proxy_set_header X-Real-IP $remote_addr; 
     # The IP address of the client (which might be a proxy itself) 
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
     proxy_pass https://adsbar-ssl; 
    } 
} 

server { 
    listen xxx.xxx.xxx.xxx:61709; 
    location /nginx_status { 
     stub_status on; 
     access_log off; 
     allow 127.0.0.1; 
     deny all; 
    } 
} 

sysctl.conf:

# Kernel sysctl configuration file for Red Hat Linux 
# 
# For binary values, 

0 is disabled, 1 is enabled. See sysctl(8) and 
# sysctl.conf(5) for more details. 

# Controls IP packet forwarding 
net.ipv4.ip_forward = 0 

# Controls source route verification 
net.ipv4.conf.default.rp_filter = 1 

# Do not accept source routing 
net.ipv4.conf.default.accept_source_route = 0 

# Controls the System Request debugging functionality of the kernel 
kernel.sysrq = 1 

# Controls whether core dumps will append the PID to the core filename 
# Useful for debugging multi-threaded applications 
kernel.core_uses_pid = 1 

# Controls the use of TCP syncookies 
net.ipv4.tcp_syncookies = 1 

# Controls the maximum size of a message, in bytes 
kernel.msgmnb = 65536 

# Controls the default maxmimum size of a mesage queue 
kernel.msgmax = 65536 

# Controls the maximum shared segment size, in bytes 
kernel.shmmax = 68719476736 

# Controls the maximum number of shared memory segments, in pages 
kernel.shmall = 4294967296 

fs.file-max = 120000 
net.ipv4.ip_conntrack_max = 131072 
net.ipv4.tcp_max_syn_backlog = 8196 
net.ipv4.tcp_fin_timeout = 25 
net.ipv4.tcp_keepalive_time = 3600 
net.ipv4.ip_local_port_range = 1024 65000 
net.ipv4.tcp_rmem = 4096 25165824 25165824 
net.core.rmem_max = 25165824 
net.core.rmem_default = 25165824 
net.ipv4.tcp_wmem = 4096 65536 25165824 
net.core.wmem_max = 25165824 
net.core.wmem_default = 65536 
net.core.optmem_max = 25165824 
net.core.netdev_max_backlog = 2500 
net.ipv4.tcp_tw_recycle = 1 
net.ipv4.tcp_tw_reuse = 1 

Bất kỳ trợ giúp, hướng dẫn, ý tưởng nào sẽ được đánh giá cao.

Trả lời

3

nginx chắc chắn sẽ có thể xử lý nhiều thì 1000 req/s (tôi nhận được khoảng 2800 req/s trong nginx khi chơi xung quanh trên máy tính xách tay giá rẻ của tôi với jmeter sử dụng một và một Halve của 2 lõi)

Bạn đang sử dụng epoll đó là tùy chọn tối ưu trên hạt nhân Linux hiện tại khi tôi hiểu nó.

Bạn đã tắt acces_log, vì vậy, bạn không thể là nút cổ chai (lưu ý: bạn cũng có thể đặt access_log thành chế độ đệm với bộ đệm lớn, nơi nó chỉ ghi sau mỗi x kb, tránh io đĩa liên tục bị búa, nhưng giữ nhật ký để phân tích)

Hiểu biết của tôi là để tối đa hóa hiệu suất nginx, bạn thường đặt số lượng worker_processes bằng số lõi/cpu và sau đó tăng số của worker_connections để cho phép nhiều kết nối đồng thời hơn (cùng với số lượng giới hạn tệp mở). Tuy nhiên, trong dữ liệu bạn đăng ở trên, bạn có một cpu quadcore với 10 quy trình công nhân với 10k kết nối cho phép mỗi. Do đó ở phía nginx tôi sẽ thử một cái gì đó như:

worker_processes 4; 
worker_rlimit_nofile 999999; 
events { 
    worker_connections 32768; 
    use epoll; 
    multi_accept on; 
} 

Về phía hạt nhân tôi muốn điều chỉnh tcp đọc và ghi bộ đệm khác nhau, bạn muốn tối thiểu nhỏ, mặc định nhỏ và lớn tối đa.

Bạn đã tăng phạm vi cổng tạm thời.

Tôi muốn các tệp mở số giới hạn nhiều hơn, vì bạn sẽ có nhiều ổ cắm mở.

Mà cho những dòng sau để thêm/thay đổi trong /etc/sysctl.conf bạn

net.ipv4.tcp_rmem = 4096 4096 25165824         
net.ipv4.tcp_wmem = 4096 4096 25165824 
fs.file-max=999999 

Hy vọng rằng sẽ giúp.

18

Dưới đây là một số tài liệu tham khảo tốt:

http://dak1n1.com/blog/12-nginx-performance-tuning

server lỗi: https://serverfault.com/questions/221292/tips-for-maximizing-nginx-requests-sec

Một cấu hình rất tốt tài liệu từ liên kết dak1n1:

# This number should be, at maximum, the number of CPU cores on your system. 
# (since nginx doesn't benefit from more than one worker per CPU.) 
worker_processes 24; 

# Number of file descriptors used for Nginx. This is set in the OS with 'ulimit -n 200000' 
# or using /etc/security/limits.conf 
worker_rlimit_nofile 200000; 


# only log critical errors 
error_log /var/log/nginx/error.log crit 


# Determines how many clients will be served by each worker process. 
# (Max clients = worker_connections * worker_processes) 
# "Max clients" is also limited by the number of socket connections available on the system (~64k) 
worker_connections 4000; 


# essential for linux, optmized to serve many clients with each thread 
use epoll; 


# Accept as many connections as possible, after nginx gets notification about a new connection. 
# May flood worker_connections, if that option is set too low. 
multi_accept on; 


# Caches information about open FDs, freqently accessed files. 
# Changing this setting, in my environment, brought performance up from 560k req/sec, to 904k req/sec. 
# I recommend using some varient of these options, though not the specific values listed below. 
open_file_cache max=200000 inactive=20s; 
open_file_cache_valid 30s; 
open_file_cache_min_uses 2; 
open_file_cache_errors on; 


# Buffer log writes to speed up IO, or disable them altogether 
#access_log /var/log/nginx/access.log main buffer=16k; 
access_log off; 


# Sendfile copies data between one FD and other from within the kernel. 
# More efficient than read() + write(), since the requires transferring data to and from the user space. 
sendfile on; 


# Tcp_nopush causes nginx to attempt to send its HTTP response head in one packet, 
# instead of using partial frames. This is useful for prepending headers before calling sendfile, 
# or for throughput optimization. 
tcp_nopush on; 


# don't buffer data-sends (disable Nagle algorithm). Good for sending frequent small bursts of data in real time. 
tcp_nodelay on; 


# Timeout for keep-alive connections. Server will close connections after this time. 
keepalive_timeout 30; 


# Number of requests a client can make over the keep-alive connection. This is set high for testing. 
keepalive_requests 100000; 


# allow the server to close the connection after a client stops responding. Frees up socket-associated memory. 
reset_timedout_connection on; 


# send the client a "request timed out" if the body is not loaded by this time. Default 60. 
client_body_timeout 10; 


# If the client stops reading data, free up the stale client connection after this much time. Default 60. 
send_timeout 2; 


# Compression. Reduces the amount of data that needs to be transferred over the network 
gzip on; 
gzip_min_length 10240; 
gzip_proxied expired no-cache no-store private auth; 
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml; 
gzip_disable "MSIE [1-6]\."; 

Ngoài ra chi tiết trên linux điều chỉnh hệ thống cho sysctl.conf:

# Increase system IP port limits to allow for more connections 

net.ipv4.ip_local_port_range = 2000 65000 


net.ipv4.tcp_window_scaling = 1 


# number of packets to keep in backlog before the kernel starts dropping them 
net.ipv4.tcp_max_syn_backlog = 3240000 


# increase socket listen backlog 
net.core.somaxconn = 3240000 
net.ipv4.tcp_max_tw_buckets = 1440000 


# Increase TCP buffer sizes 
net.core.rmem_default = 8388608 
net.core.rmem_max = 16777216 
net.core.wmem_max = 16777216 
net.ipv4.tcp_rmem = 4096 87380 16777216 
net.ipv4.tcp_wmem = 4096 65536 16777216 
net.ipv4.tcp_congestion_control = cubic 
+0

Bạn có thực hiện những thay đổi này cho cả máy chủ cân bằng tải và máy chủ phụ trợ hay cái kia hay không? –

+0

Chi tiết xin vui lòng. Mỗi máy chủ nginx có được những điều chỉnh này, nếu ở mức âm lượng cao. – chrislovecnm

+0

Tôi giả sử nếu tôi có các máy chủ cân bằng tải cơ sở dữ liệu (pgpool, không phải máy chủ nginx), nó cũng nên có các cài đặt xem xét kết nối cơ sở dữ liệu sẽ được sử dụng cho mọi yêu cầu. Ngược lại kết nối betwen pgpool và postgres sẽ không giả định các thiết lập này bởi vì có một kết nối liên tục được thiết lập giữa pgpool và postgres, do đó không phải là một kết nối tcp mới establsihed cho mọi yêu cầu cơ sở dữ liệu. Điều này có đúng không? –

2

Tôi thấy rằng việc sử dụng thuật toán ít được kết nối nhất có vấn đề. Tôi đã chuyển sang

hash $remote_addr consistent; 

và nhận thấy dịch vụ nhanh hơn nhiều.

Các vấn đề liên quan