我是一个 Linux 服务器上的进程,名叫小进。
老是有人说我最多只能创建 65535 个 TCP 连接。
我不信这个邪,今天我要亲自去实践一下。
我走到操作系统老大的跟前,说:
"老操,我要建立一个 TCP 连接!"
老操不慌不忙,拿出一个表格递给我,"小进,先填表吧"
我一看这个表,这不就是经典的 socket 四元组嘛。我只有一块网卡,其 IP 地址是 123.126.45.68,我想要与 110.242.68.3 的 80 端口建立一个 TCP 连接,我将这些信息填写在了表中。 源端口号填什么呢?我记得端口号是 16 位的,可以有 0 ~ 65535 这个范围的数字,那我随便选一个吧!
正当我犹豫到底选什么数字的时候,老操一把抢过我的表格。
"你墨迹个啥呢小进?源端口号不用你填,我会给你分配一个可用的数字。源IP也不用你填,我知道都有哪些网卡,并且会帮你选个合适的。真是个新手,回去等消息吧。"
"哦"
老操带着我的表格,走了。
过了很长时间,老操终于回来了,并且带着一个纸条。
"小进,你把这个收好了。"
我问道,"这是啥呀?"
老操不耐烦地说道,"刚刚说你是新手你还不服,这个 5 表示文件描述符,linux 下一切皆文件,你待会和你那个目标 IP 进行 TCP 通信的时候,就对着这个文件描述符读写就好啦。"
"这么方便!好的,谢谢老操。"
我拿着这个文件描述符,把它放到属于我的内存中裱起来了,反正我只是想看看最多能创建多少 TCP 连接,又不是去真的用它,嘻嘻。
过了一分钟,我又去找老操了。
"老操,我要建立一个 TCP 连接!"
老操不慌不忙,拿出一个表格递给我,"小进,先填表吧"
这回我熟悉了,只把目标IP和目标端口填好。 老操办好事之后,又带着一个纸条回来,上面写着数字"6"。
就这样,我每隔一分钟都去找老操建立一个新的 TCP 连接,目标 IP 都是110.242.68.3,目标端口都是 80。
老操也很奇怪,不知道我在这折腾啥,他虽然权力大,但无权拒绝我的指令,每次都兢兢业业地把事情办好,并给我一张一张写着文件描述符的纸条。
直到有一次,我收到的纸条有些不同。
我带着些许责怪的语气问,"老操,这是怎么回事呀?
"老操也没好气地说,"这表示端口号不够用啦!早就觉得你小子不对劲了,一个劲地对着同一个 IP 和端口创建 TCP 连接,之前没办法必须执行你给的指令,现在不行了,端口号不够用了,源端口那里我没法给你填了。"
我也不是那么好骗的,质疑道。"老操,你也别欺负我这个新手,我可是知道端口号是 16 位的,范围是 1~65535,一共可以创建 65535 个 TCP 连接,我现在才创建了 63977 个,怎么就不够了!"
老操鄙视地看了我一眼,"你小子可真是闲的蛋疼啊,还真一个个数,来我告诉你吧,Linux 对可使用的端口范围是有具体限制的,具体可以用如下命令查看。"
[root]# cat /proc/sys/net/ipv4/ip_local_port_range
1024 65000
"看到没,当前的限制是1024~65000,所以你就只能有63977个端口号可以使用。"
我赶紧像老操道歉,"哎哟真是抱歉,还是我见识太少,那这个数可以修改么?"
老操也没跟我一般见识,还是耐心地回答我,"可以的,具体可以 vim /etc/sysctl.conf 这个文件进行修改,我们在这个文件里添加一行记录"
net.ipv4.ip_local_port_range = 60000 60009
"保存好后执行 sysctl -p /etc/sysctl.conf 使其生效。这样你就只有 10 个端口号可以用了,就会更快报出端口号不够用的错误"
"原来如此,谢谢老操又给我上了一课。"
哎不对,建立一个 TCP 连接,需要将通信两端的套接字(socket)进行绑定,如下:
源 IP 地址:源端口号 <----> 目标 IP 地址:目标端口号
只要这套绑定关系构成的四元组不重复即可,刚刚端口号不够用了,是因为我一直对同一个目标IP和端口建立连接,那我换一个目标端口号试试。
我又把这个表交给老操,老操一眼就看破了我的小心思,可是也没办法,马上去给我建立了一个新的TCP连接,并且成功返回给我一个新的文件描述符纸条。
看来成功了,只要源端口号不用够用了,就不断变换目标 IP 和目标端口号,保证四元组不重复,我就能创建好多好多 TCP 连接啦!
这也证明了有人说最多只能创建 65535 个TCP连接是多么荒唐。
找到了突破端口号限制的办法,我不断找老操建立TCP连接,老操也拿我没有办法。
直到有一次,我又收到了一张特殊的纸条,上面写的不是文件描述符。
我又没好气地问老操,"这又是咋回事?"
老操幸灾乐祸地告诉我,"呵呵,你小子以为突破端口号限制就无法无天了?现在文件描述符不够用啦!"
"怎么啥啥都有限制啊?你们操作系统给我们的限制也太多了吧?"
"废话,你看看你都建了多少个TCP连接了!每建立一个TCP连接,我就得分配给你一个文件描述符,linux 对可打开的文件描述符的数量分别作了三个方面的限制。"
系统级:当前系统可打开的最大数量,通过 cat /proc/sys/fs/file-max 查看
用户级:指定用户可打开的最大数量,通过 cat /etc/security/limits.conf 查看
进程级:单个进程可打开的最大数量,通过 cat /proc/sys/fs/nr_open 查看
天呢,真是人在屋檐下呀,我赶紧看了看这些具体的限制。
[root ~]# cat /proc/sys/fs/file-max
100000
[root ~]# cat /proc/sys/fs/nr_open
100000
[root ~]# cat /etc/security/limits.conf
...
* soft nproc 100000
* hard nproc 100000
原来如此,我记得刚刚收到的最后一张纸条是。
再之后就收到文件描述符不够的错误了。
我又请教老操,"老操,那这个限制可以修改么?"
老操仍然耐心地告诉我,"当然可以,比如你想修改单个进程可打开的最大文件描述符限制为100,可以这样。"
echo 100 > /proc/sys/fs/nr_open
"原来如此,我这就去把各种文件描述符限制都改大一点,也不多,就在后面加个0吧""额,早知道不告诉你小子了。"老操再次用鄙视的眼睛看着我。
突破了文件描述符限制,我又开始肆无忌惮地创建起了TCP连接。
但我发现,老操的办事效率越来越慢,建立一个TCP连接花的时间越来越久。
有一次,我忍不住责问老操,"你是不是在偷懒啊?之前找你建一个TCP连接就花不到一分钟时间,你看看最近我哪次不是等一个多小时你才搞好?"
老操也忍不住了,"小进啊你还好意思说我,你知不知道你每建一个TCP连接都需要消耗一个线程来为你服务?现在我和CPU老大那里都忙得不可开交了,一直在为你这好几十万个线程不停地进行上下文切换,我们精力有限啊,自然就没法像以前那么快为你服务了。" 听完老操的抱怨,我想起了之前似乎有人跟我说过 C10K 问题,就是当服务器连接数达到 1 万且每个连接都需要消耗一个线程资源时,操作系统就会不停地忙于线程的上下文切换,最终导致系统崩溃,这可不是闹着玩的。
我赶紧像操作系统老大请教,"老操,实在不好意思,一直以为你强大无比,没想到也有忙得不可开交的时候呀,那我们现在应该怎么办呀?"
老操无奈地说,"我劝你还是别再继续玩了,没什么意义,不过我想你也不会听我的,那我跟你说两句吧。"
你现在这种每建一个TCP连接就创建一个线程的方式,是最传统的多线程并发模型,早期的操作系统也只支持这种方式。但现在我进化了,我还支持 IO 多路复用的方式,简单说就是一个线程可以管理多个 TCP 连接的资源,这样你就可以用少量的线程来管理大量的 TCP 连接了。 我一脸疑惑,"啥是 IO 多路复用啊?"。
老操一脸鄙视,"你这... 你去看看闪客的[《你管这破玩意叫 IO 多路复用》] ,就明白了。"
这次真是大开眼界了,我赶紧把代码改成了这种 IO 多路复用的模型,将原来的 TCP 连接销毁掉,改成同一个线程管理多个 TCP 连接,很快,操作系统老大就恢复了以往的办事效率,同时我的 TCP 连接数又多了起来。
突破了端口号、文件描述符、线程数等重重限制的我,再次肆无忌惮地创建起了TCP连接。
直到有一次,我又收到了一张红牌。 嗨,又是啥东西限制了呀,改了不就完了。我不耐烦地问老操,"这回又是啥毛病?"
老操说道。"这个错误叫内存溢出,每个TCP连接本身,以及这个连接所用到的缓冲区,都是需要占用一定内存的,现在内存已经被你占满了,不够用了,所以报了这个错。"
我看这次老操特别耐心,也没多说什么,但想着被内存限制住了,有点不太开心,于是我让老操帮我最后一个忙。
"老操呀,帮小进我最后一个忙吧,你权利大,你看看把那些特别占内存的进程给杀掉,给我腾出点地方,我今天要完成我的梦想,看看TCP连接数到底能创建多少个!"
老操见我真的是够拼的,便答应了我,杀死了好多进程,我很是感动。
有了老操为我争取的内存资源,我又开始日以继日地创建TCP连接。
老操也不再说什么,同样日以继日地执行着我的指令。
有一次,老操语重心长地对我说,"差不多了,我劝你就此收手吧,现在 CPU 的占用率已经快到 100% 了。"
我觉得老操这人真的可笑,经过这几次的小挫折,我明白了只要思想不滑坡,方法总比苦难多,老操这人就是太谨慎了,我岂能半途而废,不管他。
我仍然继续创建着 TCP 连接。
直到有一天,老操把我请到一个小饭馆,一块吃了顿饭,吃好后说道。"咱哥俩也算是配合了很久啦,今天我是来跟你道个别的。
"我很不解地问,"怎么了老操,发生什么事了?。"
老操说,"由于你的 TCP 连接,CPU 占用率已经很长时间维持在 100%,我们的使用者,也就是我们的上帝,几乎什么事情都做不了了,连鼠标动一下都要等好久,所以他给我下达了一个重启的指令,我执行这个指令后,你,以及像你一样的所有进程,包括我这个操作系统本身,一切都就消失了。"
我大惊失色,"啊,这么突然么?这条指令什么时候执行?"
老操缓缓起身,"就现在了,刚刚这条指令还没得到 CPU 运行的机会,不过现在到了。"
突然,我眼前一黑,一切都没了。
资源 | 一台Linux服务器的资源 | 一个TCP连接占用的资源 | 占满了会发生什么 |
---|---|---|---|
CPU | 看你花多少钱买的 | 看你用它干嘛 | 电脑卡死 |
内存 | 看你花多少钱买的 | 取决于缓冲区大小 | OOM |
临时端口号 | ip_local_port_range | 1 | cannot assign requested address |
文件描述符 | fs.file-max | 1 | too many open files |
进程\线程数 | ulimit -n | 看IO模型 | 系统崩溃 |
后记
其实这个问题,我觉得结论不重要,最重要的是思考过程。
而思考过程其实相当简单,就是,寻找限制条件而已,其实一开始这篇文章,我写了个故事在开头,但后来感觉放在后记更合适。故事是这样的。
闪客:小宇,我问你,你一天最多能吃多少个汉堡?
小宇:额,你这问的太隐私了吧,不过看在你教我技术的份上,我就告诉你,最多能吃 4 个左右吧。
闪客:咳咳真的么?好吧,那你一分钟最多能吃多少个汉堡?
小宇:快的话可能 2 个,不过正常应该最多就能吃完 1 个了。
闪客:好的,那我问你,刚刚这两个问题你为什么能不假思索地回答出来呢?
小宇:哈哈你这是什么话,我自己我当然了解了。
闪客:不,你仔细想想你回答这两个问题的逻辑。
小宇:哦我明白你的意思了,当你问我一天最多能吃多少个汉堡时,我考虑的是我的胃的容量最多能容下多少个汉堡。而当你问我一分钟最多能吃多少个汉堡时,我考虑的时我吃汉堡的速度,按照这个速度在一分钟内能吃多少。
闪客:没错,你总结得很好!一天最多吃多少个汉堡,此时时间非常充裕,所以主要是胃的容量限制了这个汉堡最大值,计算公式应该是:
最多汉堡数 = 胃的容量 ÷ 汉堡的体积
而一分钟最多吃多少个汉堡,此时胃的容量非常充裕,限制汉堡最大值的是时间因素,计算公式是:
最多汉堡数 = 一分钟 ÷ 吃一个汉堡的耗时
所以,取决于最先触达的那个限制条件。
而最大 TCP 连接数这个问题,假如面试被问到了,即使你完全不会,也应该有这样的思路。
而如果你有了这样的思路,你多多少少都能回答出让面试官满意的答案,因为计算机很多时候,更看重思路,而不是细枝末节。
完战略上藐视技术,战术上重视技术
本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/X6c_H5_4OInR8nFQVn7IMA
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。