范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

对面试必问tcp还是一知半解?最浅显易懂的高并发架构TCP知识详解

  做为一个有追求的程序员,不能只满足增删改查,我们要对系统全方面无死角掌控。掌握了这些基本的网络知识后,相信一方面日常排错中会事半功倍,另一方面日常架构中不得不考虑的高并发问题,理解了这些底层协议也是会如虎添翼。
  本文不会单纯给大家讲讲TCP三次握手、四次挥手就完事了。如果只是哪样的话,我直接贴几个连接就完事了。我希望把实际工作中的很多点能够串起来讲给大家。当然为了文章完整,我依然会从 三次握手 起头。再说TCP状态变更过程
  不管是三次握手、还是四次挥手,他们都是完成了TCP不同状态的切换。进而影响各种数据的传输情况。下面从三次握手开始分析。 三次握手
  来看看三次握手的图,估计大家看这图都快看吐了,不过为什么每次面试、回忆的时候还是想不起呢?我再来抄抄这锅剩饭吧!
  首先当服务端处于 listen 状态的时候,我们就可以再客户端发起监听了,此时客户端会处于 SYN_SENT 状态。服务端收到这个消息会返回一个 SYN 并且同时 ACK 客户端的请求,之后服务端便处于 SYN_RCVD 状态。这个时候客户端收到了服务端的 SYN&ACK,就会发送对服务端的 ACK,之后便处于 ESTABLISHED 状态。服务端收到了对自己的 ACK 后也会处于 ESTABLISHED 状态。
  经常在面试中可能有人提问:为什么握手要3次,不是2次或者4次呢?
  首先说4次握手,其实为了保证可靠性,这个握手次数可以一直循环下去;但是这没有一个终止就没有意义了。所以3次,保证了各方消息有来有回就足够了。当然这里可能有一种情况是,客户端发送的 ACK 在网络中被丢了。那怎么办?其实大部分时候,我们连接建立完成就会立刻发送数据,所以如果服务端没有收到 ACK 没关系,当收到数据就会认为连接已经建立;如果连接建立后不立马传输数据,那么服务端认为连接没有建立成功会周期性重发 SYN&ACK 直到客户端确认成功。
  再说为什么2次握手不行呢?2次握手我们可以想象是没有三次握手最后的 ACK, 在实际中确实会出现客户端发送 ACK 服务端没有收到的情况(上面的情况一),那么这是否说明两次握手也是可行的呢? 看下情况二,2次握手当服务端发送消息后,就认为建立成功,而恰巧此时又没有数据传输。这就会带来一种资源浪费的情况。比如:客户端可能由于延时发送了多个连接情况,当服务端每收到一个请求回复后就认为连接建立成功,但是这其中很多求情都是延时产生的重复连接,浪费了很多宝贵的资源。
  因此综上所述,从资源节省、效率3次握手都是最合适的。话又回来三次握手的真实意义其实就是协商传输数据用的:序列号与窗口大小。
  下面我们通过抓包再来看一下真实的情况是否如上所述。20:33:26.583598 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [S], seq 621839080, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 1050275400 ecr 0,sackOK,eol], length 0 20:33:26.660754 IP 103.235.46.39.80 > 192.168.0.102.58165: Flags [S.], seq 1754967387, ack 621839081, win 8192, options [mss 1452,nop,wscale 5,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,sackOK,eol], length 0 20:33:26.660819 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [.], ack 1754967388, win 4096, length 0
  抓包: sudo tcpdump -n host www.baidu.com -S
  S 表示 SYN . 表示 ACK P 表示 传输数据 F 表示 FIN四次挥手
  挥手,就是说数据传完了,同志们再见!
  这里有个问题需要注意下,其实客户端、服务端都能够主动发起关闭操作,谁调用 close() 就先发送关闭的请求。当然一般的流程,发起建立连接的一方会主动发起关闭请求(http中)。
  关于4次挥手的过程,我就不多解释了,这里有两个重要的状态我需要解释下,这都是我亲自经历过的线上故障,close_wait 与 time_wait。
  先给大家一个命令,统计tcp的各种状态情况。下面表格内容就来自这个命令的统计。
  netstat -n | awk "/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}"
  大量的CLOSE_WAIT 这个在我之前的一篇文章已经有过介绍,它会导致大量的socket无法释放。而每个socket都是一个文件,是会占用资源的。这个问题主要是代码问题。它出现在被动关闭的一方(习惯称为server)。
  大量的TIME_WAIT 这个问题在日常中经常看到,流量一高就出现大量的该情况。该状态出现在主动发起关闭的一方。该状态一般等待的时间设为 2MSL后自动关闭,MSL是Maximum Segment Lifetime,报文最大生存时间,如果报文超过这个时间,就会被丢弃。处于该状态下的socket也是不能被回收使用的。线上我就遇到这种情况,每次大流量的时候,每台机器处于该状态的socket就多达10w+,远远比处于 Established 状态的socket多的多,导致很多时候服务响应能力下降。这个一方面可以通过调整内核参数处理,另一方面避免使用太多的短链接,可以采用连接池来提升性能。另外在代码层面可能是由于某些地方没有关闭连接导致的,也需要检查业务代码。
  上面两个状态一定要牢记发生在哪一方,这方便我们快速定位问题。
  最后这里还是放上挥手时的抓包数据:20:33:26.750607 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [F.], seq 621839159, ack 1754967720, win 4096, length 0 20:33:26.827472 IP 103.235.46.39.80 > 192.168.0.102.58165: Flags [.], ack 621839160, win 776, length 0 20:33:26.827677 IP 103.235.46.39.80 > 192.168.0.102.58165: Flags [F.], seq 1754967720, ack 621839160, win 776, length 0 20:33:26.827729 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [.], ack 1754967721, win 4096, length 0
  不多不少,刚好4次。TCP状态变更
  网络上有一张TCP状态机的图,我觉得太复杂了,用自己的方式搞个简单点的容易理解的。我从两个角度来说明状态的变更。一个是客户端一个是服务端
  看下面两张图的时候,请一定结合上面三次握手、四次挥手的时序图一起看,加深理解。客户端状态变更
  通过这张图,大家是否能够清晰明了的知道 TCP 在客户端上的变更情况了呢? 服务端状态变更
  这一张图描述了 TCP 状态在服务端的变迁。
  相关视频推荐
  《tcp/ip详解卷一》: 150行代码拉开协议栈实现的篇章
  10道网络八股文,每道都很经典,让你在面试中逼格满满
  学习地址:C/C++Linux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂
  需要C/C++ Linux服务器架构师学习资料加qun812855908获取(资料包括 C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg 等),免费分享
  TCP的流量控制与拥塞控制
  我们常说TCP是面向连接的,UDP是无连接的。那么TCP这个面向连接主要解决的是什么问题呢?
  这里继续把三次握手的抓包数据贴出来分析下:20:33:26.583598 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [S], seq 621839080, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 1050275400 ecr 0,sackOK,eol], length 0 20:33:26.660754 IP 103.235.46.39.80 > 192.168.0.102.58165: Flags [S.], seq 1754967387, ack 621839081, win 8192, options [mss 1452,nop,wscale 5,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,sackOK,eol], length 0 20:33:26.660819 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [.], ack 1754967388, win 4096, length 0
  上面我们说到 TCP 的三次握手最重要的就是协商传输数据用的序列号。那这个序列号究竟有些什么用呢?这个序号能够帮助后续两端进行确认数据包是否收到,解决顺序、丢包问题;另外我们还可以看到有一个 win 字段,这是双方交流的窗口大小,这在每次传输数据过程中也会携带。主要是告诉对方,我窗口是这么大,别发多了或者别发太少。
  总结下,TCP的几个特点是:顺序问题,依靠序号丢包问题,依靠序号流量控制,依靠滑动窗口拥塞控制,依靠拥塞窗口+滑动窗口连接维护,三次握手/四次挥手顺序与丢包问题
  这个问题其实应该很好理解。由于数据在传输前我们已经有序号了,这里注意一下这个序号是随机的,重复的概率极地,避免了程序发生乱入的可能性。
  由于我们每个数据包有序号,虽然发送与到达可能不是顺序的,但是TCP层收到数据后,可以根据序号进行重新排列;另外在这个排列过程中,发现有了1,2,3,5,6这几个包,一检查就知道4要么延时未到达,要么丢包了,等待重传。
  这里需要重要说明的一点是。为了提升效率,TCP其实并不是收到一个包就发一个ack。那是如何ACK的呢?还是以上面为例,TCP收到了1,2,3,5,6这几个包,它可能会发送一个 ack ,seq=3 的确认包,这样次一次确认了3个包。但是它不会发送 5,6 的ack。因为4没有收到啊!一旦4延时到达或者重发到达,就会发送一个 ack, seq=6,又一次确认了3个包。流量控制与拥塞控制
  这两个概念说实话,让我理解了挺长时间,主要是对它们各自控制的内容以及相互之间是否有作用一直没有闹清楚。
  先大概说下:流量控制:是根据接收方的窗口大小来感知我这次能够传多少数据给对方;———— 滑动窗口拥塞控制:而拥塞控制主要是避免网络拥塞,它考虑的问题更多。根据综合因素来觉得发多少数据给对方;———— 滑动窗口&拥塞窗口
  举个例子说下,比如:A给B发送数据,通过握手后,A知道B一次可以收1000的数据(B有这么大的处理能力),那么这个时候滑动窗口就可以设置成1000。那是不是最后真的可以一次发这么多数据给B呢?还不是,这时候得问问拥塞窗口,老兄,现在网络情况怎么样?一次运1000的数据有压力吗?拥塞窗口一通计算说不行,现在是高峰期,最多只能有600的货上路。最终这次传数据的时候就是 600 的标注。大家也可以关注抓包数据的 win 值,一直在动态调整。
  当然另外一种情况是滑动窗口比拥塞窗口小,虽然运输能力强,但是接收能力有限,这时候就要取滑动窗口的值来实际发生。所以它们二者之间是有关系的。
  所以具体到每次能够发送多少数据,有这么一个公式:
  LastByteSend - LastByteAcked <= min{cwnd,rwnd}LastByteSend 是最后一个发送的字节的序号LastByteAcked 最后一个被确认的字节的序号
  这两个相减得到的是本次能够发送的数据,这个数据一定小于或等于 cwnd 与 rwnd 中最小的一个值。相信大家能够理清楚。
  那么这部分知识对于实际工作中有什么作用呢?指导意义就是:如果你的业务很重要、很核心一定不要混布;二是如果你的服务忽快忽慢,而确信依赖服务没有问题,检查下机器对应的网络情况;三是窗口这个速度控制机制,在我们进行服务设计的时候,非常具有参考意义。是不是有点消息队列的感觉?(很多消息队列都是匀速的,我们是否可以加一个窗口的概念来进行优化呢?)是什么限制了你的连接
  到了最关键的地方了,精华我都是留到最后讲。下面放一张网上找的socket操作步骤图,画的太好了我就直接用了。
  我们假设我的服务端就是 Nginx ,我来尝试解读一下。当客户端调用 connect() 时候就会发起三次握手,这次握手的时候有几个元素唯一确定了这次通信(或者说这个socket),[源IP:源Port, 目的IP:目的Port] ,当然这个socket还不是最终用来传输数据的socket,一旦握手完成后,服务端会在返回一个 socket 专门用来后续的数据传输。这里暂且把第一个socket叫 监听socket,第二个叫 传输socket 方便后文叙述。
  为什么要这么设计呢?大家想一想,如果监听的socket还要负责数据的收发,请问这个服务端的效率如何提升?什么东西、谁都往这个socket里边丢,太复杂!提高连接常用套路
  到了这一步,我们现在先停下来算算自己的服务器机器能够有多少连接呢?这个极限又是如何一步步被突破呢?
  先说 监听socket ,服务器的prot一般都是固定的,服务器的ip当然也是固定的(单机)。那么上面的结构 [源IP:源Port, 目的IP:目的Port] 其实只有客户端的ip与端口可以发生变化。假设客户端用的是IPv4,那么理论连接数是:2^32(ip数) * 2^16(端口数) = 2^48。
  看起来这个值蛮大的。但是真的能够有这么多连接吗?不可能的,因为每一个socket都需要消耗内存;以及每一个进程的文件描述符是有上限的。这些都限制了最终的连接数。
  那么如何进行调和呢?我知道的操作有:多进程、多线程、IO多路服用、协程等手段组合使用。多进程
  也就是监听是一个进程,一旦accept后,对于 传输socket 我们就fork一个新的子进程来处理。但是这种方式太重,fork一个进程、销毁一个进程都是特别费事的。单机对进程的创建上限也是有限制的。多线程
  线程比进程要轻量级的多,它会共享父进程的很多资源,比如:文件描述符、进程空间,它就是多了一个引用。因此它的创建、销毁更加容易。每一个 传输socket 在这里就交给了线程来处理。
  但是不管是多进程、还是多线程都存在一个问题,一个连接对应一个进程或者协程。这都很难逃脱 C10K 的问题。那么该怎么办呢?IO多路复用
  IO多路复用是什么意思呢?在上面单纯的多进程、多线程模型中,一个进程或线程只能处理一个连接。用了IO多路复用后,我一个进程或线程就能处理多个连接。
  我们都知道 Nginx 非常高效,它的结构是:master + worker,worker 会在 80、443端口上来监听请求。它的worker一般设置为 cpu 的cores数,那么这么少的子进程是如何解决超多连接的呢?这里其实每个worker就采用了 epoll 模型(当然IO多路复用还有个select,这里就不说了)。
  处于监听状态的worker,会把所有 监听socket 加入到自己的epoll中。当这些socket都在epoll中时,如果某个socket有事件发生就会立即被回调唤醒(这涉及epoll的红黑树,讲不清楚不细说了)。这种模式,大大增加了每个进程可以管理的socket数量,上限直接可以上升到进程能够操作的最大文件描述符。
  一般机器可以设置百万级别文件描述符,所以单机单进程就是百万连接,epoll是解决C10K的利器,很多开源软件用到了它。
  这里说下,并不是所有的worker都是同时处于监听端口的状态,这涉及到nginx惊群、抢自旋锁的问题,不再本文范围内不多说。关于ulimit
  在文章的最后,补充一些单机文件描述符设置的问题。我们常说连接数受限于文件描述符,这是为什么?
  因为在linux上一切皆文件,故每一个socket都是被当作一个文件看待,那么每个文件就会有一个文件描述符。在linux中每一个进程中都有一个数组保存了该进程需要的所有文件描述符。这个文件描述符其实就是这个数组的 key ,它的 value 是一个指针,指向的就是打开的对应文件。
  关于文件描述符有两点注意:它对应的其实是一个linux上的文件文件描述符本身这个值在不同进程中是可以重复的
  另外补充一点,单机设置的ulimit的上线受限与系统的两个配置:fs.nr_open,进程级别
  fs.file-max,系统级别
  fs.nr_open 总是应该小于等于 fs.file-max,这两个值的设置也不是随意可以操作,因为设置的越大,系统资源消耗越多,所以需要根据真实情况来进行设置。
  至此,本篇长文就完结了。

中金公司5G落地及人工智能发展AIoT进入发展快车道中金公司指出,随着5G落地及人工智能发展,AIoT进入发展快车道。我国5G基站数达到115。9万,5G网络基本实现全覆盖。未来5G的建设重点将转向应用场景探索及落地,以智能驾驶智慧上线两年用户突破2亿腾讯会议正加速开放21世纪经济报道记者白杨北京报道近日,腾讯会议迎来了两周岁的生日。自2019年12月25日正式上线起,在疫情推动用户线上协同需求快速增长的背景下,腾讯会议上线短短8个月就积累了1亿个人可不可以自己想个饮料的名字,找工厂代工来批发?完全可以,别说饮料,各行各业都有,国内某知名白酒品牌不生产一滴酒,还不是一样混得风生水起。首先你要注册一个商标,给你的产品取个响亮的名字,然后办理各种合法手续,如果你不知道怎么办,起步价33。5万的坦克500居然卖爆了?难道是人傻钱多嘛?在2021年广州车展上,可以新能源车成为主角以及中国品牌车型卖的越来越贵这两大趋势,而坦克500就是其中的代表。坦克500在广州车展上正式开起全国预售,共推出商务版运动版及定制版三实体清单又添丁!国科微新华三中科微等12家中企上榜今日热点1。美商务部再出手,12家中企及机构被新增列入实体清单2。半导体厂房建设投资创历史新高SEMI明年近270亿美元3。机械硬盘已淘汰?EPIC创始人表示SSD未来才是主流4。离职京东员工吐槽一年竞业协议只补偿3个月,从此京东一生黑竞业协议是如今很多大型企业都会签订的合同,虽然签订竞业协议对于大部分员工来说都不太公平,离职后在一年内不能去竞争公司上班,很不利于自己找到一份好工作,但同时也能拿到公司一年的补贴。百度抢跑元宇宙,用当下的失望赌一把未来?百度将今年的开发者大会放到了自家发布的元宇宙产品希壤中。但关于希壤,不少体验者的第一感受是,失望。尽管顶着新奇的元宇宙名号,但目前希壤给人的印象,就是一款网游。而且,制作和图像渲染电商聚合供应链系统开发app聚合供应链即为FS2B2C模式。直接找邓森I76電883I薇5I52(即整合厂家F端,各大供应链平台S端,通过大数据手段,赋能于线上电商平台商品需求及线下商家商品采集)供应链系统是喵喵机家用打印机F1,孩子学习辅助神器,家长的好帮手打印机这种设备以前都是办公来使用,但是随着人们生活水平的提高,家里孩子的学习也与它密不可分了,只要孩子上了小学基本就成了家家必备了!小学开始逐渐增加的课程和家庭作业加上家长们快节奏老牌厂商亮剑,骁龙888Plus256GB五千电池,到手价仅2199元如果你不经常关注手机圈的话,可能以为小米12是全球首发骁龙8Gen1处理器的手机,其实并不是,全球首发骁龙8Gen1的手机来自老牌厂商摩托罗拉发布的EdgeX30,这款手机开售初还令特鲁多失望了?孟晚舟回到中国第88天,外媒曝出华为5G好消息一段时间以来,美国为了维护自身的霸权地位,频繁采取各种方式打压和遏制中国发展,而这也使得不少唯美国马首是瞻的国家开始盲从美国针对中国,比如说曾在孟晚舟事件中充当帮凶一角的加拿大。据
无惧潮湿!有了它,不倒水不插电循环用!一天吸走一杯水南方的世界,不止有苟且,还有湿和远方。才送走了凛凛寒冬,潮湿多雨的回南天又到访了!家里阳台晾了5天还没干的衣服,潮得可以掐出水来的床单,甚至家里的各个位置都开始发霉衣服鞋子墙角柜边提神第一步,选对咖啡杯!怎么也推不倒,喵星人都抓不倒的那种每天一杯咖啡,是很多人开始一天工作和学习的标配。但就装咖啡的杯子,常常造成不小的悲剧,正所谓杯碎坑钱包,水洒湿衣裳。咖啡杯被碰倒了弄脏衣服事小,可万一洒在笔记本电脑上就悲剧了搞不好低配车加装倒车雷达,完全指望维修师傅?这几点建议,收好不谢前面说过的,讲究性价比,买次低配或合适的中配车,后期再加装是不错的选择。尤其是合资车,低配版本简直没人性,很多基本驾驶辅助功能也减配了,比如倒车雷达。不过市面上,可以选择加装的倒车用四年一加5后再换一加9,亲身体验告诉你,手机为什么要买旗舰机今年的秋天,学弟学妹们即将进入大学校园,而我也刚刚离开校园进入职场。和四年之前一样,做的第一件事,就是换一部手机。实际上,我的一加5依然流畅,只是电池有些不耐用了,所以我还是会把它买车选低配还是高配?别再到处问了,告诉你,懂车的人都这样选有车一族经常抱怨路况差停车难油价高,似乎汽车对于他们来说更像是一种负担。可是看看汽车市场每年的销量,又觉得很矛盾。嘴上说说而已,买汽车不仅仅是用来代步的,更多的是考虑面子以及归属感怎么选适合自己品类的外卖包装?者大碗。(点上图知识卡片,按右上角箭头,可分享至朋友圈保存)在这个重颜值的时代,消费者对于外卖包装的诉求在逐渐提高,在餐品质量差异不大的前提下,那些包装好的商品,更具市场竞争力,能什么样的房间最适合做家庭影院?需要注意哪些细节呢?随着家庭影院逐渐被人们所认识,越来越多的人想要在家中置办上家庭影院,一来可以进行看电影娱乐,另一方面还能改变家装,是现在必不可少的家装设备之一。对家庭影院稍作了解的人们都清楚,家庭在未来的家居生活中,我们都能够得到哪些舒适的智能服务呢?全屋智能家居今天咱们来聊一下全屋智能家居如何布置?该布置方案为主流户型三房两厅而设计,所包含的智能家居有智能门锁安防报警系统全屋照明系统全屋背景音乐系统智能电动窗帘智能家电控制远程家庭影院小白,如何在客厅构建适合自己的家庭影院?现代年轻人的生活越发多姿多彩,看电影作为时下流行的休闲方式,而备受现代人的青睐!许多人周末或有空闲时都会到电影院去看电影,享受电影大作所带来的视觉盛宴,但随着社会整体消费升级,大家明星为何纷纷在北京朝阳区出事?这是一个神奇的地方朝阳区是文化大区,明星们爱扎堆住朝阳。朝阳群众被传得神乎其神,其实背后是一套科学方法和体系。作者今纶李云迪因为嫖娼在北京朝阳区栽了。为什么又是朝阳区?据不完全统计,从2014年起,限制明星代言信用卡,是否有些矫枉过正日前,监管机构出台了关于警惕明星代言金融产品风险的提示,主要针对P2P平台非法集资产品互联网金融平台,以及一些类金融投资机构,邀请明星代言推广或站台,存在过度宣传承诺高额回报误导性