Как добиться 500 000 запросов в секунду на моем веб-сервере?
Недавно я подарил себе новый выделенный сервер, и я пытаюсь выжать из него максимальную производительность для развлечения и обучения.
Я пытаюсь достичь максимально возможных запросов в секунду, которые этот сервер может обработать, и нацеливаюсь на 500K запросов / сек, как упомянуто здесь - http://lowlatencyweb.wordpress.com/2012/03/20/500000-requestssec-modern-http-servers-are-fast/
Детали сервера
Intel® Xeon® E3-1270 4 ядра (8 HT) x 3,4 ГГц
ОЗУ 24 ГБ DDR3 ECC
Место на жестком диске 2000 ГБ (2 x 2000 SATA) RAID Программное обеспечение RAID 1
Lan 100 Мбит / с
ОС Centos 6.3 64 бит
Nginx
Я могу достичь только 35K запросов / сек для статического TXT-файла. Я запускаю тест на той же машине. Я знаю об ограничениях NIC и сетевых издержках
ab -n100000 -c200 http://localhost/test.txt
Обновление - 165K запросов / сек
Я попробовал другой инструмент для тестирования wrk
и это дало мне 165K запросов / сек. Так круто!
Обновление 2 - 250 тыс. Запросов / сек
nginx.conf
#######################################################################
#
# This is the main Nginx configuration file.
#
# More information about the configuration options is available on
# * the English wiki - http://wiki.nginx.org/Main
# * the Russian documentation - http://sysoev.ru/nginx/
#
#######################################################################
#----------------------------------------------------------------------
# Main Module - directives that cover basic functionality
#
# http://wiki.nginx.org/NginxHttpMainModule
#
#----------------------------------------------------------------------
user nginx;
worker_processes 8;
worker_rlimit_nofile 262144;
error_log /var/log/nginx/error.log;
#error_log /var/log/nginx/error.log notice;
#error_log /var/log/nginx/error.log info;
pid /var/run/nginx.pid;
#----------------------------------------------------------------------
# Events Module
#
# http://wiki.nginx.org/NginxHttpEventsModule
#
#----------------------------------------------------------------------
events {
worker_connections 16384;
multi_accept on;
use epoll;
}
#----------------------------------------------------------------------
# HTTP Core Module
#
# http://wiki.nginx.org/NginxHttpCoreModule
#
#----------------------------------------------------------------------
http {
include /etc/nginx/mime.types;
index index.php index.html index.htm;
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;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
server_tokens off;
client_max_body_size 24m;
client_body_buffer_size 128k;
#keepalive_timeout 0;
keepalive_timeout 65;
open_file_cache max=1000;
open_file_cache_min_uses 10;
open_file_cache_errors on;
gzip on;
gzip_static on;
gzip_comp_level 3;
gzip_disable "MSIE [1-6]\.";
gzip_http_version 1.1;
gzip_vary on;
gzip_proxied any;
gzip_types text/plain text/css text/xml text/javascript text/x-component text/cache-manifest application/json application/javascript application/x-javascript application/xml application/rss+xml application/xml+rss application/xhtml+xml application/atom+xml application/wlwmanifest+xml application/x-font-ttf image/svg+xml image/x-icon font/opentype app/vnd.ms-fontobject;
gzip_min_length 1000;
fastcgi_cache_path /tmp levels=1:2
keys_zone=NAME:10m
inactive=5m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
server {
listen 80;
server_name _;
root /var/www/html;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
try_files $uri $uri/ /index.php?$args;
}
error_page 404 /404.html;
location = /404.html {
root /var/www/error;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/error;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# checks to see if the visitor is logged in, a commenter,
# or some other user who should bypass cache
set $nocache "";
if ($http_cookie ~ (comment_author_.*|wordpress_logged_in.*|wp-postpass_.*)) {
set $nocache "Y";
}
# bypass cache if logged in.
# Be sure that this is above all other fastcgi_cache directives
fastcgi_no_cache $nocache;
fastcgi_cache_bypass $nocache;
fastcgi_cache NAME;
fastcgi_cache_valid 200 302 10m;
fastcgi_cache_valid 301 1h;
fastcgi_cache_valid any 1m;
fastcgi_cache_min_uses 10;
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_buffers 256 16k;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# Deny access to any files with a .php extension in the uploads directory
location ~* ^/wp-content/uploads/.*.php$ {
deny all;
access_log off;
log_not_found off;
}
location ~* \.(jpg|jpeg|gif|png|flv|mp3|mpg|mpeg|js|css|ico)$ {
expires max;
log_not_found off;
}
}
}
4 ответа
Прежде всего, вы должны написать новый инструмент для тестирования. Вы на самом деле бенчмаркинг ab
не nginx
,
Arpit, если вы представите, что самый маловероятный ответ в сети, даже если это статический текстовый файл, представляет собой один пакет Ethernet (~1500 байт), то 500 000 из них работают на 750 000 000 байт, или примерно 7,5 гигабит. Поэтому, если ваш сервер не очень легко выгружает сетевые адаптеры 10 Гбит (а это не так, то вы получаете в сто раз медленнее) и не настроили драйверы и ядро, чтобы вы могли почти полностью заполнить одну из этих ссылок, плюс Задержки балансировщиков нагрузки, брандмауэров, маршрутизаторов и последующих подключений с такой скоростью не позволят вам достичь такой производительности - даже при одном ответе пакета, что маловероятно. Так что в конечном итоге 35k звучит не далеко от вашего лимита.
Давайте определим узкое место. Поскольку вы находитесь на одной и той же машине, мы можем предположить, что это активность процессора или диска. Для одного текстового файла это не должно быть дисковой активностью, но при 35 тыс. Подключениях вы можете генерировать 35 МБ журналирования также каждую секунду.
Примеры, которые вы показываете, не запускают регистрацию доступа, только ошибки. Ваша конфигурация, однако, имеет гораздо больше информации, в частности:
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;
Начните с отключения этой регистрации, а затем выясните, где вы зависаете на следующем. Также учтите, что запуск тестового клиента на одной и той же машине может оказать заметное влияние на демон сервера. Hypertheading также может иногда быть вредным, поэтому посмотрите, работает ли он лучше для вашей нагрузки, когда включен или выключен.
Если вы просто набираете цифры [например, за этим тестом нет реального варианта использования] - сделайте ab использовать функцию поддержания активности http - выполните количество запросов через уже открытое TCP-соединение.