Ubuntu nginx静态内容服务器奇怪流量问题

Ubuntu nginx静态内容服务器奇怪流量问题

我有一台运行 nginx 1.9.3 的 Ubuntu 15.10,用于提供静态内容,这些内容主要是图像和视频文件。没有其他自定义进程在运行,甚至不会消耗 1% 的服务器资源。没有 PHP 处理,也没有发生任何 SQL 数据库连接。

的输出netstat -an | wc -l始终在 700-1500 个 tcp 连接范围内。在 95% 的情况下,大多数用户请求下载某个 3.5 MB 的视频文件(nginx 访问日志证实了这一点),由于 nginx 和 linux 本身的缓存机制,我确信该文件始终存储在 RAM 中。事实上 - 的输出iotop告诉我大多数时候磁盘读取率为 0 - 0.5%,所以我知道我遇到的问题与磁盘 I/O 无关。

运行nload3 小时后我发现我的流量如下:

Curr: 103.41 MBit/s
Avg: 73.97 MBit/s
Min: 14.62 MBit/s
Max: 457.88 MBit/s
Ttl: 141357.91 GByte

每当 TCP 连接数超过约 1200 时,用户从服务器加载数据时就会遇到延迟/超时。

让我详细说明一下迄今为止我对这些“延迟/超时”的观察:

我几乎可以肯定 nginx 配置不是问题所在,因为不仅仅是 HTTP 连接会超时,而且即使只是从另一台计算机 ping(ICMP)服务器,当达到上述 tcp 连接标记时,我也会收到很多“请求超时”的结果。

当我在 Windows 上运行 Wireshark 并在浏览器中加载这段 3.5 MB 的视频时(在上述高负载期间),我看到很多标有

[TCP ACKed unseen segment] [TCP Previous segment not captured]

这意味着这个视频文件的某些块(数据包)不是发表对我来说。这让我想到我的问题很可能与我的服务器的 NIC 无法处理所有流量有关outgoing,或者托管我服务器的托管公司存在带宽/流量限制。然而,经过多次询问,他们向我保证,他们没有设置流量限制,这对我当前的带宽消耗来说不会是一个问题。

我进行的下一个测试是捕获从我的 Windows 操作系统到我的服务器的 ping 请求/回复 - 在 Windows 和tcpdumpUbuntu 上使用 Wireshark。结果几乎总是如下(在高负载期间):

在 Ubuntu 上,我可以看到每个 ICMP Ping 请求数据包都与一个 Ping 回复数据包匹配。这里没有任何问题。在 Windows 上,20 个 ICMP Ping 请求数据包中有 5-6 个没有接收其匹配的 Ping Reply 数据包。

由此我知道,CPU 级别的服务器可以正确查看和处理连接,而且只有在向网络接口(NIC)发送数据包(回复)之后或之后才会出现问题。

以下是我的 nginx 配置、网络接口和服务器信息:

nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;

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

worker_rlimit_nofile 25000;

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 15;
    types_hash_max_size 2048;
    # server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

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

        client_max_body_size 500M; 

    ##
    # SSL Settings
    ##

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    #access_log off;
        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/javascript text/xml application/xml application/xml+rss text/javascript;

    ##
    # Virtual Host Configs
    ##


        open_file_cache          max=2000 inactive=20s;
        open_file_cache_valid    60s;
        open_file_cache_min_uses 5;
        open_file_cache_errors   off;        

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

/etc/nginx/站点可用/默认

server {
    listen 80 backlog=4096 default_server;
    listen [::]:80 default_server;

    # SSL configuration
    #
    # listen 443 ssl default_server;
    # listen [::]:443 ssl default_server;
    #
    # Note: You should disable gzip for SSL traffic.
    # See: https://bugs.debian.org/773332
    #
    # Read up on ssl_ciphers to ensure a secure configuration.
    # See: https://bugs.debian.org/765782
    #
    # Self signed certs generated by the ssl-cert package
    # Don't use them in a production server!
    #
    # include snippets/snakeoil.conf;

    root /var/www/html;

    # Add index.php to the list if you are using PHP
    index index.php index.html index.htm index.nginx-debian.html;

    server_name 93.188.8.60;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
    }

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
    #
    #   # With php5-cgi alone:
    #   fastcgi_pass 127.0.0.1:9000;
    #   # With php5-fpm:
        fastcgi_read_timeout 900; 
                fastcgi_pass unix:/var/run/php5-fpm.sock;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    location ~ /\.ht {
        deny all;
    }
}

ifconfig 的输出txqueuelen(注:我在尝试各种网卡优化来解决这个问题时修改了参数)

eno1      Link encap:Ethernet  HWaddr 30:5a:3a:56:39:bc
          inet addr:93.188.8.60  Bcast:93.188.8.255  Mask:255.255.255.0
          inet6 addr: fe80::325a:3aff:fe56:39bc/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:50327240672 errors:0 dropped:173244 overruns:0 frame:0
          TX packets:104203043819 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:5000
          RX bytes:4067795598631 (4.0 TB)  TX bytes:151795336718586 (151.7 TB)
          Interrupt:20 Memory:fb200000-fb220000

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:133764933 errors:0 dropped:0 overruns:0 frame:0
          TX packets:133764933 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:10569844193 (10.5 GB)  TX bytes:10569844193 (10.5 GB)

输出sysctl -a

https://pastebin.com/zv86U9jn

注意:我修改了几个参数,例如:

net.core.somaxconn
net.core.netdev_max_backlog
net.ipv4.tcp_max_syn_backlog 

尝试解决这个问题。

ulimit -n 900000当我想到这个问题可能与每个进程允许打开的文件数量有关时,我也感到很沮丧。

我的服务器规格:

主板:华硕X99-A

CPU:由于cat /proc/cpuinfo输出中的“型号名称”,我无法确定 CPU 的确切 Core i7 型号Genuine Intel(R) CPU @ 2.40GHz ,但我知道它有 24 个内核,以下是输出cat /proc/cpuinfohttps://pastebin.com/TR7aS1NM

内存:64 GB

硬盘:4TB 希捷

网卡:板载英特尔® I218V,1 个千兆 LAN 控制器

我已经为这个问题苦苦挣扎了 1 周了。NIC 是导致此问题的原因吗?也许我的假设是错误的?我可以提供所需的任何其他命令输出。

相关内容