Назад | Перейти на главную страницу

Как достичь 500 тыс. Запросов в секунду на моем веб-сервере?

Недавно я подарил себе новый выделенный сервер и стараюсь выжать из него максимальную производительность для развлечения и обучения.

Я пытаюсь достичь максимально возможных запросов в секунду, которые может обрабатывать этот сервер, и стремлюсь к 500 тыс. Запросов в секунду, как упоминалось здесь - 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

Место на жестком диске 2 000 ГБ (2 x 2 000 SATA) RAID Программный RAID 1

Lan 100 Мбит / с

ОС Centos 6.3 64 бит

Nginx

Я могу получить только 35 КБ запросов в секунду для статического файла txt. Я запускаю тест на той же машине. Я знаю об ограничениях сетевого адаптера и накладных расходах сети

ab -n100000 -c200 http://localhost/test.txt

Обновить - 165 тыс. Запросов / сек.

Я попробовал другой инструмент для тестирования, который называется wrk и он дал мне 165 тысяч запросов в секунду. Так круто!

Обновление 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;
}
}

}

Arpit, если вы вообразите, что самый маленький вероятный веб-ответ, даже если это статический текстовый файл, - это один пакет Ethernet (~ 1500 байт), тогда 500 000 из них будут иметь размер около 750 000 000 байт, или примерно 7,5 гигабита. Так что, если ваш сервер не очень легко разгрузил сетевые карты 10 Гб (а это не так, тот, который у вас есть, в сто раз медленнее) и не настроил драйверы и ядро, чтобы вы могли почти полностью заполнить одну из этих ссылок, а также задержки балансировщиков нагрузки, брандмауэров, маршрутизаторов и последующих подключений с такой скоростью, тогда вы никогда не сможете достичь такой производительности - даже с одним ответом на пакет, что маловероятно. Так что в конечном итоге 35k звучат недалеко от вашего предела.

Прежде всего, вам следует написать новый инструмент для тестирования производительности. Вы на самом деле сравниваете ab не nginx.

Определим узкое место. Поскольку вы находитесь на одной машине, мы можем предположить, что это либо ЦП, либо диск. Для одного текстового файла это не должно быть дисковой активностью, но при 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;

Начните с отключения этого журнала, а затем выясните, где вы в следующий раз зависнете. Также учтите, что запуск тестового клиента на том же компьютере может оказать заметное влияние на серверный демон. Гипертеги также иногда могут быть вредными, поэтому подумайте, работает ли это лучше для вашей нагрузки, когда она включена или выключена.

если вы следите сразу за числами [например, за этим тестом нет реального варианта использования] - заставьте ab использовать функцию сохранения активности http - выполнить количество запросов через уже открытое TCP-соединение.