如何实现百万级本地TCP并发连接?.NET 8应用测试求助
本地Ubuntu服务器实现百万级TCP并发连接的配置方案
一、系统内核参数调优
Linux内核默认TCP参数无法支撑百万级连接,需修改/etc/sysctl.conf添加以下配置,执行sysctl -p生效(重启系统可持久化设置):
# 系统总文件句柄数,需大于进程最大文件句柄限制 fs.file-max = 1000000 # TCP连接资源回收优化 net.ipv4.tcp_tw_reuse = 1 # 复用TIME_WAIT状态套接字 net.ipv4.tcp_fin_timeout = 30 # 缩短FIN_WAIT_2超时时间(默认60s) net.ipv4.tcp_max_tw_buckets = 2000000 # 扩大TIME_WAIT桶上限,避免溢出 # 连接队列优化 net.core.somaxconn = 100000 # 监听队列最大长度,需与应用backlog配置匹配 net.ipv4.tcp_max_syn_backlog = 100000 # SYN队列长度,防止连接建立时溢出 net.core.netdev_max_backlog = 100000 # 网络设备接收队列长度 # 端口范围与保活设置 net.ipv4.ip_local_port_range = 1024 65535 # 扩大本地可用端口范围(默认32768-65535) net.ipv4.tcp_keepalive_time = 600 # 10分钟后发起保活探测 net.ipv4.tcp_keepalive_intvl = 60 # 探测间隔60s net.ipv4.tcp_keepalive_probes = 3 # 3次探测失败则断开连接 # 缓冲区优化(回环/本地连接必备) net.core.rmem_max = 16777216 # 最大接收缓冲区16MB net.core.wmem_max = 16777216 # 最大发送缓冲区16MB net.ipv4.tcp_rmem = 4096 87380 16777216 # TCP接收缓冲区范围 net.ipv4.tcp_wmem = 4096 65536 16777216 # TCP发送缓冲区范围
二、进程资源限制补充
仅修改limits.conf可能不生效,需完成以下操作:
- 修改
/etc/security/limits.conf,设置全局进程文件句柄限制:* soft nofile 1048576 * hard nofile 1048576 root soft nofile 1048576 root hard nofile 1048576 - 确保
/etc/pam.d/common-session包含该行(无则添加):session required pam_limits.so - 重启系统或重新登录用户,执行
ulimit -a确认open files的软/硬限制均为1048576。
三、虚拟机环境配置
本地测试用虚拟机需调整以下配置:
- 内存分配:单服务器虚拟机至少分配8GB以上内存(每个TCP连接约占用10-20KB内存,百万连接需10-20GB);客户端虚拟机按连接数比例分配内存(如10万连接分配2GB)。
- 网络模式:使用桥接模式或内部网络,避免NAT模式的端口转发限制;内部网络性能更优,适合本地高并发测试。
- 关闭安全限制:
- 关闭UFW防火墙:
ufw disable - 临时关闭AppArmor:
systemctl stop apparmor && systemctl disable apparmor
- 关闭UFW防火墙:
四、测试端优化
- 分摊连接压力:不要用单进程/单虚拟机创建所有连接,拆分至多个客户端进程或虚拟机(如10个客户端实例,每个承担10万连接)。
- 控制连接建立速度:避免瞬间发起大量连接(触发SYN flood保护),可每建立1000个连接添加100ms延迟,或用异步批量建立逻辑。
- 客户端参数匹配:客户端同样需设置文件句柄限制(同服务器端配置),避免客户端自身资源瓶颈。
五、代码层面适配
- 监听队列匹配:服务器监听时设置
backlog参数等于net.core.somaxconn的值,比如ASP.NET Core配置:builder.WebHost.ConfigureKestrel(options => { options.ListenAnyIP(8080, opt => opt.Backlog = 100000); }); - 异步IO模式:确保服务器/客户端均使用异步IO(.NET 8 async/await或SocketAsyncEventArgs),避免为每个连接创建线程。
- 资源释放:连接关闭时需主动释放资源(如WebSocket.CloseAsync、Socket.DisposeAsync),防止内存泄漏。
内容的提问来源于stack exchange,提问作者ygoe
相关产品推荐
相关产品推荐

