默认
打赏 发表评论 23
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少
阅读(403775) | 评论(23 收藏62 淘帖1 7
微信扫一扫关注!

前言


曾几何时我们还在寻求网络编程中C10K问题(有关C10K问题请见文章《The C10K problem(英文在线阅读英文PDF版下载中文译文)》)的解决方案,但是现在从硬件和操作系统支持来看单台服务器支持上万并发连接已经没有多少挑战性了。

我们先假设单台服务器最多只能支持万级并发连接,其实对绝大多数应用来说已经远远足够了,但是对于一些拥有很大用户基数的互联网公司,往往面临的并发连接数是百万、千万、甚至腾讯的上亿(注:QQ默认用的UDP协议,具体请见讨论贴《为什么QQ用的是UDP协议而不是TCP协议?》)。

虽然现在的集群,分布式技术可以为我们将并发负载分担在多台服务器上,那我们只需要扩展出数十台电脑就可以解决问题,但是我们更希望能更大的挖掘单台服务器的资源,先努力垂直扩展,再进行水平扩展,这样可以有效的节省服务器相关的开支(硬件资源、机房、运维人力、电力其实也是一笔不小的开支)。

那么到底一台服务器能够支持多少TCP并发连接呢?这就是本文要讨论的问题。

C10K问题系列文章


本文是C10K问题系列文章中的第1篇,总目录如下:

常识一:文件句柄限制


在linux下编写网络服务器程序的朋友肯定都知道每一个tcp连接都要占一个文件描述符,一旦这个文件描述符使用完了,新的连接到来返回给我们的错误是“Socket/File:Can't open so many files”。

这时你需要明白操作系统对可以打开的最大文件数的限制。

1进程限制


执行 ulimit -n 输出 1024,说明对于一个进程而言最多只能打开1024个文件,所以你要采用此默认配置最多也就可以并发上千个TCP连接。临时修改:ulimit -n 1000000,但是这种临时修改只对当前登录用户目前的使用环境有效,系统重启或用户退出后就会失效。

重启后失效的修改(不过我在CentOS 6.5下测试,重启后未发现失效),编辑 /etc/security/limits.conf 文件, 修改后内容为:

  • soft nofile 1000000
  • hard nofile 1000000

永久修改:编辑/etc/rc.local,在其后添加如下内容:

  • ulimit -SHn 1000000

2全局限制


执行 cat /proc/sys/fs/file-nr 输出 9344 0 592026,分别为:

  • 1. 已经分配的文件句柄数,
  • 2. 已经分配但没有使用的文件句柄数,
  • 3. 最大文件句柄数。

但在kernel 2.6版本中第二项的值总为0,这并不是一个错误,它实际上意味着已经分配的文件描述符无一浪费的都已经被使用了 。

我们可以把这个数值改大些,用 root 权限修改 /etc/sysctl.conf 文件:

  • fs.file-max = 1000000
  • net.ipv4.ip_conntrack_max = 1000000
  • net.ipv4.netfilter.ip_conntrack_max = 1000000

常识二:端口号范围限制?


操作系统上端口号1024以下是系统保留的,从1024-65535是用户使用的。由于每个TCP连接都要占一个端口号,所以我们最多可以有60000多个并发连接。我想有这种错误思路朋友不在少数吧?(其中我过去就一直这么认为)

我们来分析一下吧。

如何标识一个TCP连接:
系统用一个4四元组来唯一标识一个TCP连接:{local ip, local port,remote ip,remote port}。好吧,我们拿出《UNIX网络编程:卷一》第四章中对accept的讲解来看看概念性的东西,第二个参数cliaddr代表了客户端的ip地址和端口号。而我们作为服务端实际只使用了bind时这一个端口,说明端口号65535并不是并发量的限制。

server最大tcp连接数:
server通常固定在某个本地端口上监听,等待client的连接请求。不考虑地址重用(unix的SO_REUSEADDR选项)的情况下,即使server端有多个ip,本地监听端口也是独占的,因此server端tcp连接4元组中只有remote ip(也就是client ip)和remote port(客户端port)是可变的,因此最大tcp连接为客户端ip数×客户端port数,对IPV4,不考虑ip地址分类等因素,最大tcp连接数约为2的32次方(ip数)×2的16次方(port数),也就是server端单机最大tcp连接数约为2的48次方。

本文小结


上面给出的结论都是理论上的单机TCP并发连接数,实际上单机并发连接数肯定要受硬件资源(内存)、网络资源(带宽)的限制,至少对我们的需求现在可以做到数十万级的并发了,你的呢?

(原文链接:http://yaocoder.blog.51cto.com/2668309/1312821/,有改动)

更多文章


TCP/IP详解 - 第11章·UDP:用户数据报协议
TCP/IP详解 - 第17章·TCP:传输控制协议
TCP/IP详解 - 第18章·TCP连接的建立与终止
TCP/IP详解 - 第21章·TCP的超时与重传
技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)
通俗易懂-深入理解TCP协议(上):理论基础
通俗易懂-深入理解TCP协议(下):RTT、滑动窗口、拥塞处理
理论经典:TCP协议的3次握手与4次挥手过程详解
理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程
计算机网络通讯协议关系图(中文珍藏版)
UDP中一个包的大小最大能多大?
P2P技术详解(一):NAT详解——详细原理、P2P简介
P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解
P2P技术详解(三):P2P技术之STUN、TURN、ICE详解
通俗易懂:快速理解P2P技术中的NAT穿透原理
不为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)
不为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)
不为人知的网络编程(三):关闭TCP连接时为什么会TIME_WAIT、CLOSE_WAIT
不为人知的网络编程(四):深入研究分析TCP的异常关闭
不为人知的网络编程(五):UDP的连接性和负载均衡
不为人知的网络编程(六):深入地理解UDP协议并用好它
不为人知的网络编程(七):如何让不可靠的UDP变的可靠?
网络编程懒人入门(一):快速理解网络通信协议(上篇)
网络编程懒人入门(二):快速理解网络通信协议(下篇)
网络编程懒人入门(三):快速理解TCP协议一篇就够
网络编程懒人入门(四):快速理解TCP和UDP的差异
网络编程懒人入门(五):快速理解为什么说UDP有时比TCP更有优势
网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门
网络编程懒人入门(七):深入浅出,全面理解HTTP协议
网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接
网络编程懒人入门(九):通俗讲解,有了IP地址,为何还要用MAC地址?
技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解
让互联网更快:新一代QUIC协议在腾讯的技术实践分享
现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障
聊聊iOS中网络编程长连接的那些事
移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”
移动端IM开发者必读(二):史上最全移动弱网络优化方法总结
IPv6技术详解:基本概念、应用现状、技术实践(上篇)
IPv6技术详解:基本概念、应用现状、技术实践(下篇)
从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路
脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手
脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?
脑残式网络编程入门(三):HTTP协议必知必会的一些知识
脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)
脑残式网络编程入门(五):每天都在用的Ping命令,它到底是什么?
脑残式网络编程入门(六):什么是公网IP和内网IP?NAT转换又是什么鬼?
以网游服务端的网络接入层设计为例,理解实时通信的技术挑战
迈向高阶:优秀Android程序员必知必会的网络基础
全面了解移动端DNS域名劫持等杂症:技术原理、问题根源、解决方案等
美图App的移动端DNS优化实践:HTTPS请求耗时减小近半
Android程序员必知必会的网络通信传输层协议——UDP和TCP
IM开发者的零基础通信技术入门(一):通信交换技术的百年发展史(上)
IM开发者的零基础通信技术入门(二):通信交换技术的百年发展史(下)
IM开发者的零基础通信技术入门(三):国人通信方式的百年变迁
IM开发者的零基础通信技术入门(四):手机的演进,史上最全移动终端发展史
IM开发者的零基础通信技术入门(五):1G到5G,30年移动通信技术演进史
IM开发者的零基础通信技术入门(六):移动终端的接头人——“基站”技术
IM开发者的零基础通信技术入门(七):移动终端的千里马——“电磁波”
IM开发者的零基础通信技术入门(八):零基础,史上最强“天线”原理扫盲
IM开发者的零基础通信技术入门(九):无线通信网络的中枢——“核心网”
IM开发者的零基础通信技术入门(十):零基础,史上最强5G技术扫盲
IM开发者的零基础通信技术入门(十一):为什么WiFi信号差?一文即懂!
IM开发者的零基础通信技术入门(十二):上网卡顿?网络掉线?一文即懂!
>> 更多同类文章 ……

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

上一篇:P2P技术详解(四):P2P技术之STUN、TURN、ICE详解下一篇:高性能网络编程(二):上一个10年,著名的C10K并发连接问题

本帖已收录至以下技术专辑

推荐方案
评论 23
学习了!!!
不错的哇
签名: 嘿嘿
一个进程能打开的最大文件个数是10M个(没有尝试过把这个值改大,也不知道能否改大),也就是104万的样子, 换句话说,服务端绑定一个端口port,则可以接受最大100万个连接。  服务器上启动100个进程,每个进程都绑定一个不同的端口,呵呵, 理论上就能支持100万*100 个连接了。
签名: TCP好难
引用:Sadhorse 发表于 2018-07-12 15:13
一个进程能打开的最大文件个数是10M个(没有尝试过把这个值改大,也不知道能否改大),也就是104万的样子, ...

你了解一下Linux下的Epoll网络模型
引用:JackJiang 发表于 2018-07-12 15:18
你了解一下Linux下的Epoll网络模型

Linux的Epoll还算了解, 目前使用的,或生产上实际场景是, 部分服务承载了上万个连接。
不知道这个最大连接数和epoll有什么关系? 或你想表达的是另一层的意思?

对于C10m  问题,  没有相应的硬件资源做验证, 不过看过有人在ucloud上 用两台机器,一个是当服务器,一个当客户端,服务器上启动多个进程, 绑定不同的端口号, 然后客户端去连接。 最终压测到几百万个TCP连接。
签名: TCP好难
引用:Sadhorse 发表于 2018-07-12 15:31
Linux的Epoll还算了解, 目前使用的,或生产上实际场景是, 部分服务承载了上万个连接。
不知道这个最大 ...

我的理解是,TCP的连接并不是真正的物理“连接”,更多的是逻辑“连接通路”,而一个同时百万连接的服务器,1秒内的真正活跃的连接(或者说有数据通信的连接)并没有这么多,可以除以10甚至更多,所以如果从系统层到代码,优化得当的理论上还是比较可行的。
长知识了
签名: 下雨了,今天不热,心情凉快
引用:JackJiang 发表于 2018-07-12 15:39
我的理解是,TCP的连接并不是真正的物理“连接”,更多的是逻辑“连接通路”,而一个同时百万连接的服务 ...

对。TCP “连接”的真正含义,指的是四元组的两端都同时维护了一种状态,所以概念上我们认为是连接状态。
引用:陈大立春 发表于 2018-08-07 13:10
对。TCP “连接”的真正含义,指的是四元组的两端都同时维护了一种状态,所以概念上我们认为是连接状态。

嗯嗯
Windows是否存在类似的文件句柄的限制呢?如果有,如何解决?
学习了,谢谢
签名: 加油啊
学习了,多谢
有没有人知道单机LVS负载均衡,能支撑多少TCP连接接入,能超过100万长连接吗,不做业务处理,仅仅是连接上来,收发心跳。
引用:yaohuan 发表于 2020-09-09 17:45
有没有人知道单机LVS负载均衡,能支撑多少TCP连接接入,能超过100万长连接吗,不做业务处理,仅仅是连接上 ...

那得看心跳频率了
引用:JackJiang 发表于 2020-09-09 17:47
那得看心跳频率了

一般能达到多少
学习
学习了
签名: read the fucking source code
学习
签名: 初来乍到
"也就是server端单机最大tcp连接数约为2的48次方",这里是不是应该是一个server的一个端口最大TCP连接数?
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部