我有一台运行 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 无关。
运行nload
3 小时后我发现我的流量如下:
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 和tcpdump
Ubuntu 上使用 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
注意:我修改了几个参数,例如:
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/cpuinfo
:https://pastebin.com/TR7aS1NM
内存:64 GB
硬盘:4TB 希捷
网卡:板载英特尔® I218V,1 个千兆 LAN 控制器
我已经为这个问题苦苦挣扎了 1 周了。NIC 是导致此问题的原因吗?也许我的假设是错误的?我可以提供所需的任何其他命令输出。