一、操作系统级限制
1. 文件描述符(FD)数量限制
- 问题:每个TCP连接占用一个FD,默认系统限制通常为
1024
,无法支撑百万连接。 - 解决方案:
-
验证:# 修改系统全局限制/etc/sysctl.conf * fs.file-max = 1048576 sysctl -p # 或修改用户级限制(如修改 /etc/security/limits.conf) * soft nofile 1048576 * hard nofile 1048576 # 或临时修改 ulimit -n 1048576
ulimit -n
查看当前进程限制。
2. 端口号范围限制
- 问题:客户端发起连接时,每个连接需要占用一个临时端口(默认范围
32768-60999
,约2.8万个端口)。 - 解决方案:
-
注意:单客户端最多发起约6.4万连接(# 扩展端口范围 echo "net.ipv4.ip_local_port_range = 1024 65535" >> /etc/sysctl.conf sysctl -p
65535 - 1024
)。 - 所以如果你想建立100万的tcp连接,怎么突破呢?
- 每个tcp连接有5个元素,源端ip、源端port、目标端ip、目标端port和协议tcp。
- 在目标端ip、目标端port固定的情况下,单客户端最多发起约6.4万连接(
65535 - 1024
),只能增加客户端数量,绑定不同源端ip发送请求,如采用20个客户端; - 或者服务端监听多个socket,每个socket采用不同的端口号port。例如监听20个端口,客户端分别连接这20个端口
3. 内存限制
- 问题:每个TCP连接占用内核内存(约
3-4KB
),100万连接需约3-4GB
内存。 - 解决方案:优化内核参数
echo "net.ipv4.tcp_mem = 1024000 1048576 2048000" >> /etc/sysctl.conf # 调整TCP内存管理 echo "net.ipv4.tcp_rmem = 1024 1024 2048" >> /etc/sysctl.conf # 减少读缓冲区 echo "net.ipv4.tcp_wmem = 1024 1024 2048" >> /etc/sysctl.conf # 减少写缓冲区 sysctl -p
- 使用sysctl net.ipv4.tcp_mem命令可查看系统的net.ipv4.tcp_mem配置值,同理查看其他配置
4.连接跟踪表限制
- 问题:
net.netfilter.nf_conntrack_max
是 Linux 内核中控制 连接跟踪表(Connection Tracking Table)最大容量 的关键参数。它决定了系统能同时跟踪的网络连接(如 TCP、UDP、ICMP 等)的最大数量 - 解决方案:
-
echo "net.netfilter.nf_conntrack_max = 1048576" >> /etc/sysctl.conf # 调整连接跟踪表 sysctl -p
二、网络协议栈优化
1. TCP连接建立速度
- 问题:三次握手过程中,服务端
SYN队列
和ACCEPT队列
可能溢出。 - 优化:(一般使用默认值即可,除非进程处理连接比较慢导致连接队列溢出,可优化程序)
-
echo "net.ipv4.tcp_max_syn_backlog = 65536" >> /etc/sysctl.conf # SYN队列大小 echo "net.core.somaxconn = 65536" >> /etc/sysctl.conf # ACCEPT队列大小 echo "net.ipv4.tcp_syncookies = 0" >> /etc/sysctl.conf # 关闭SYN Cookie(高并发时可能降低性能) sysctl -p
2. TIME_WAIT 连接累积
- 问题:主动关闭连接的一方会进入
TIME_WAIT
状态,占用端口资源。 - 优化:(一般使用默认值即可,除非你是同时大量断开tcp)
-
echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.conf # 允许重用TIME_WAIT端口 echo "net.ipv4.tcp_max_tw_buckets = 2000000" >> /etc/sysctl.conf # 增加TIME_WAIT桶数量 sysctl -p
三、服务端程序优化
1. 使用epoll模式(非常重要,使用select和poll是无法完成百万并发的)