如何在我的网络服务器上实现每秒 500K 个请求?

如何在我的网络服务器上实现每秒 500K 个请求?

我最近给自己买了一台新的专用服务器,为了娱乐和学习,我想最大限度地发挥它的性能。

我正在尝试实现该服务器每秒可以处理的最大请求数,目标是达到这里提到的 500K 个请求/秒 -http://lowlatencyweb.wordpress.com/2012/03/20/500000-requestssec-modern-http-servers-are-fast/

服务器详细信息

英特尔® 至强® E3-1270 4 核(8 HT)x 3.4 GHz

内存 24 GB DDR3 ECC

硬盘空间 2,000 GB (2 x 2,000 SATA) RAID 软件 RAID 1

局域网 100mbps

操作系统 Centos 6.3 64位

Nginx

对于静态 txt 文件,我只能达到每秒 35K 个请求。我正在同一台机器上运行基准测试。我知道 NIC 限制和网络开销

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

更新- 165K 请求/秒

我尝试了另一个基准测试工具wrk,它给了我每秒 165K 个请求。太酷了!

更新 2- 250K 个请求/秒

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

}

答案1

首先,你应该编写一个新的基准测试工具。你实际上是在进行基准测试,ab而不是nginx

答案2

Arpit,如果你认为绝对最小的可能网络响应(即使它是一个静态文本文件)是一个以太网数据包(~1,500 字节),那么 500,000 个数据包大约相当于 750,000,000 字节,或大约 7.5 千兆位。因此,除非你的服务器能够非常轻松地卸载 10Gb NIC(但实际上并没有,你拥有的那个网卡要慢一百倍),并且已经设置了驱动程序和内核,允许你几乎完全淹没其中一个链接,再加上负载平衡器、防火墙、路由器和以该速率进行的后续连接的延迟,否则你将永远无法达到这种性能 - 即使只有一个数据包响应,这也是不太可能的。因此,最终 35k 听起来离你的极限并不远。

答案3

让我们找出瓶颈。由于您在同一台机器上,我们可以假设它是 CPU 或磁盘活动。对于一个文本文件,它不应该是磁盘活动,但在 35k 个连接下,您可能每秒也会生成 35MB 的日志记录。

您展示的示例不运行访问日志记录,只运行错误日志记录。但是,您的配置还有很多事情要做,尤其是日志记录:

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;

首先禁用该日志记录,然后找出下一个挂起的位置。还要考虑在同一台机器上运行测试客户端可能会对服务器守护进程产生明显影响。超线程有时也会产生危害,因此请探索在开启或关闭时,它是否更有利于您的负载。

答案4

如果您只是追求数字 [例如,这个测试背后没有实际用例] - 让 ab 使用 http 的保持活动功能 - 通过已经打开的 TCP 连接执行一定数量的请求。

相关内容