- 0 四元组:
- 1 访问一个URL经历了哪些过程
- 2 HTTP 请求分为三个部分
- 3 GET和POST区别
- 4 base64过后的字符串可以通过get传输吗 ?
- 5 TCP与UDP之间的区别
- 6 HTTPS通信步骤
- 8 TCP 的特性
- 9 三次握手
- 10 四次挥手
- 11 UDP
- 12 访问的网站是如何切到https的
- 13 SYN攻击
- 14 TCP
- 15 HTTPS和HTTP的区别主要如下
- 31 http1.0有哪些痛点
- 16 HTTP/2 有哪些缺陷?HTTP/3 做了哪些优化?
- 19 TCP如何实现流量控制?
- 20 什么是零窗口(接收窗口为0时会怎样)?
- 21 浏览器在与服务器建立了一个 TCP 连接后是否会在一个 HTTP 请求完成后断开?什么情况下会断开?
- 23 一个 TCP 连接中 HTTP 请求发送可以一起发送么
- 24 HTTP/1.1 时代,浏览器是如何提高页面加载效率的
- 25 DNS解析
- 26 域名解析用UDP协议?
- 27 区域传送时使用TCP
- 28 网络的性能指标有哪些
- 30 什么是对称加密、非对称加密?区别是什么?
- 33 Client如何实现长连接
- 34 http能不能一次连接多次请求,不等后端返回
- 35 HTTP2.0和HTTP1.X相比的新特性
- 36 http3.0 为什么要使用UDP协议
- 38 HTTPS采用的加密
0 四元组:
-
1 访问一个URL经历了哪些过程
客户端获取URL
- DNS解析(根据域名查询IP地址时,浏览器会使用Socket库中的解析器。)
- TCP连接
- 发送HTTP请求,浏览器向服务器发送一条http请求报文
- 服务器处理请求
- 返回报文
- 浏览器解析渲染页面
-
2 HTTP 请求分为三个部分
状态行(方法,url,协议版本)
- 请求头(换行符之类的)
-
3 GET和POST区别
GET产生一个TCP数据包;POST产生两个TCP数据包。
- 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据); 而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
- GET是通过URL提交数据,GET可提交的数据量就跟URL所能达到的最大长度有直接关系。(参数过长会有415错误,不同浏览器限制不一样)
- HTTP协议没有对POST进行任何限制,一般是受服务器配置限制或者内存大小。
大多数框架都是尽量在一个tcp包里面把HTTP请求发出去的,但是也确实存在先发HTTP头,然后发body的框架。但是具体发多少个TCP包,这个是代码的问题,是tcp协议栈的问题,跟HTTP没关系。
4 base64过后的字符串可以通过get传输吗 ?
需要对其进行url编码,因为base64字符串可以包含“+”,“=”和“/”字符,这些字符可能会改变数据的含义
5 TCP与UDP之间的区别
TCP是面向连接的协议,而UDP是无连接(即发送数据之前不需要建立连接)的协议。(面向连接就类似打电话,无连接就类似写信。)
- TCP提供交付保证?,这意味着一个使用TCP协议发送的消息是保证交付给客户端的。UDP是不可靠的,它不提供任何交付的保证。一个数据报包在运输途中可能会丢失。
- 超时重传:当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
- 校验和:TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段。
- 流量控制:TCP连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的我数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP使用的流量控制协议是可变大小的滑动窗口协议。
- 拥塞控制:当网络拥塞时,减少数据的发送。
- TCP保证了消息的有序性,该消息将以从服务器端发出的同样的顺序发送到客户端,UDP不提供任何有序性或序列性的保证,数据包将以任何可能的顺序到达。
- 为了保证数据包的可靠传递,发送方必须把已发送的数据包保留在缓冲区;
- 并为每个已发送的数据包启动一个超时定时器;
- 如在定时器超时之前收到了对方发来的应答信息(可能是对本包的应答,也可以是对本包后续包的应答),则释放该数据包占用的缓冲区;
- 否则,重传该数据包,直到收到应答或重传次数超过规定的最大次数为止。
- 接收方收到数据包后,先进行CRC校验,如果正确则把数据交给上层协议,然后给发送方发送一个累计应答包,表明该数据已收到,如果接收方正好也有数据要发给发送方,应答包也可方在数据包中捎带过去。
- 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信。
- TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道。
- TCP是面向字节流的,UDP是面向报文的;
- TCP有拥塞控制机制,UDP没有。网络出现的拥塞不会使源主机的发送速率降低,这对某些实时应用是很重要的,比如媒体通信,游戏;
- TCP首部开销(20字节)比UDP首部开销(8字节)要大
- UDP 的主机不需要维持复杂的连接状态表
- 什么时候选择TCP,什么时候选UDP?
- 对某些实时性要求比较高的情况,选择UDP,比如游戏,媒体通信,实时视频流(直播),即使出现传输错误也可以容忍;其它大部分情况下,HTTP都是用TCP,因为要求传输的内容可靠,不出现丢失
HTTP可以使用UDP吗?(https3.0底层就是使用的UDP了)
用户在浏览器里输入一个支持 HTTPS 协议的网址,例如 https://www.baidu.com,此时会发起一个HTTPS请求,通过TCP和服务器建立连接,其中使用443端口。
- 服务器向客户端发送证书,其中包括域名,申请证书的公司,证书的公钥等信息。
- 客户端通过 SSL 或 TLS 对证书进行解析,验证公钥是否有效,例如验证颁发机构与验证过期时间等信息,如果发现证书异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个密钥,然后向服务器发送证书公钥加密后的密钥。
- 服务器用证书私钥进行解密,获得客户端传过来的密钥。
- 服务器用客户端的密钥加密后的信息发送给客户端。
- 客户端用密钥解密服务端传过来的信息,验证服务端传过来的信息是否可以用密钥进行解密。
-
8 TCP 的特性
TCP 提供一种面向连接的、可靠的字节流服务
- 在一个 TCP 连接中,仅有两方进行彼此通信。广播和多播不能用于TCP
- TCP 使用校验和,确认和重传机制来保证可靠传输
- TCP 给数据分节进行排序,并使用累积确认保证数据的顺序不变和非重复
- TCP 使用滑动窗口机制来实现流量控制,通过动态改变窗口的大小进行拥塞控制
TCP 并不能保证数据一定会被对方接收到,因为这是不可能的。TCP 能够做到的是,如果有可能,就把数据递送到接收方,否则就(通过放弃重传并且中断连接这一手段)通知用户。因此准确说TCP也不是100%可靠的协议,它所能提供的是数据的可靠递送或故障的可靠通知。
9 三次握手
是指建立一个 TCP 连接时,需要客户端和服务器总共发送3个包。三次握手的目的是连接服务器指定端口,建立 TCP 连接,并同步连接双方的序列号和确认号,交换 TCP 窗口大小信息。在 socket 编程中,客户端执行 connect() 时。将触发三次握手.
- ACK —— 确认,使得确认号有效。
- SYN —— 用于初如化一个连接的序列号。
- FIN —— 该报文段的发送方已经结束向对方发送数据。
- 第一次握手(SYN=1, seq=x)
- 客户端发送一个 TCP 的 SYN 标志位置1的包,指明客户端打算连接的服务器的端口,以及初始序号 X,保存在包头的序列号(Sequence Number)字段里。发送完毕后,客户端进入 SYN_SEND 状态。
- 第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1)
- 服务器发回确认包(ACK)应答。即 SYN 标志位和 ACK 标志位均为1。服务器端选择自己 ISN 序列号,放到 Seq 域里,同时将确认序号(Acknowledgement Number)设置为客户的 ISN 加1,即X+1。 发送完毕后,服务器端进入 SYN_RCVD 状态。
- 第三次握手(ACK=1,ACKnum=y+1)
- 客户端再次发送确认包(ACK),SYN 标志位为0,ACK 标志位为1,并且把服务器发来 ACK 的序号字段+1,放在确定字段中发送给对方,并且在数据段放写ISN的+1,发送完毕后,客户端进入 ESTABLISHED 状态,当服务器端接收到这个包时,也进入 ESTABLISHED 状态,TCP 握手结束。
- 第一次握手(SYN=1, seq=x)
- 辅助理解
- 客户端发送一个SYN段,并指明客户端的初始序列号,即ISN(c).
- 服务端发送自己的SYN段作为应答,同样指明自己的ISN(s)。为了确认客户端的SYN,将ISN(c)+1作为ACK数值。这样,每发送一个SYN,序列号就会加1. 如果有丢失的情况,则会重传。
为了确认服务器端的SYN,客户端将ISN(s)+1作为返回的ACK数值。
- TCP建立连接可以两次握手吗?为什么?
- 可能会出现已失效的连接请求报文段又传到了服务器端。
- client 发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达 server。本来这是一个早已失效的报文段。但 server 收到此失效的连接请求报文段后,就误认为是 client 再次发出的一个新的连接请求。于是就向 client 发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要 server 发出确认,新的连接就建立了。由于现在 client 并没有发出建立连接的请求,因此不会理睬 server 的确认,也不会向 server 发送数据。但 server 却以为新的运输连接已经建立,并一直等待 client 发来数据。这样,server 的很多资源就白白浪费掉了。采用 “三次握手” 的办法可以防止上述现象发生。例如刚才那种情况,client 不会向 server 的确认发出确认。server 由于收不到确认,就知道 client 并没有要求建立连接。
- 两次握手无法保证Client正确接收第二次握手的报文(Server无法确认Client是否收到),也无法保证Client和Server之间成功互换初始序列号。
- 采用四次握手吗?为什么?
- 可以。但是会降低传输的效率。四次握手是指:第二次握手:Server只发送ACK和acknowledge number;而Server的SYN和初始序列号在第三次握手时发送;原来协议中的第三次握手变为第四次握手。出于优化目的,四次握手中的二、三可以合并。
- 第三次握手中,如果客户端的ACK未送达服务器,会怎样?
- Server端:由于Server没有收到ACK确认,因此会重发之前的SYN+ACK(默认重发五次,之后自动关闭连接进入CLOSED状态),Client收到后会重新传ACK给Server。
- Client端,两种情况:
- 在Server进行超时重发的过程中,如果Client向服务器发送数据,数据头部的ACK是为1的,所以服务器收到数据之后会读取 ACK number,进入 establish 状态
- 在Server进入CLOSED状态之后,如果Client向服务器发送数据,服务器会以RST包应答。
如果已经建立了连接,但客户端出现了故障怎么办
TCP 的连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),也叫做改进的三次握手。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行 close() 操作即可产生挥手操作。
- 第一次挥手(FIN=1,seq=x)
- 假设客户端想要关闭连接,客户端发送一个 FIN 标志位置为1的包,表示自己已经没有数据可以发送了,但是仍然可以接受数据。发送完毕后,客户端进入 FIN_WAIT_1 状态。
- 第二次挥手(ACK=1,ACKnum=x+1)
- 服务器端确认客户端的 FIN 包,发送一个确认包,表明自己接受到了客户端关闭连接的请求,但还没有准备好关闭连接。发送完毕后,服务器端进入 CLOSE_WAIT 状态,客户端接收到这个确认包之后,进入 FIN_WAIT_2 状态,等待服务器端关闭连接。
- 第三次挥手(FIN=1,seq=y)
- 服务器端准备好关闭连接时,向客户端发送结束连接请求,FIN 置为1。发送完毕后,服务器端进入 LAST_ACK 状态,等待来自客户端的最后一个ACK。
- 第四次挥手(ACK=1,ACKnum=y+1)
- 客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入 TIME_WAIT状态,等待可能出现的要求重传的ACK包。服务器端接收到这个确认包之后,关闭连接,进入CLOSED状态。客户端等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入CLOSED状态。
四次挥手的示意图如下:
- 客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入 TIME_WAIT状态,等待可能出现的要求重传的ACK包。服务器端接收到这个确认包之后,关闭连接,进入CLOSED状态。客户端等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入CLOSED状态。
- 为什么不能把服务器发送的ACK和FIN合并起来,变成三次挥手(CLOSE_WAIT状态意义是什么)?
- 因为服务器收到客户端断开连接的请求时,可能还有一些数据没有发完,这时先回复ACK,表示接收到了断开连接的请求。等到数据发完之后再发FIN,断开服务器到客户端的数据传送。
- 如果第二次挥手时服务器的ACK没有送达客户端,会怎样?
- 客户端没有收到ACK确认,会重新发送FIN请求。
- 客户端TIME_WAIT状态的意义是什么?
- 第四次挥手时,客户端发送给服务器的ACK有可能丢失,TIME_WAIT状态就是用来重发可能丢失的ACK报文。如果Server没有收到ACK,就会重发FIN,如果Client在2*MSL的时间内收到了FIN,就会重新发送ACK并再次等待2MSL,防止Server没有收到ACK而不断重发FIN。MSL(Maximum Segment Lifetime),指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
- TCP四次挥手中客户端的最后一次挥手为什么要等待两个MSL?
- 等待两个MSL时间主要目的是怕最后一个 ACK包服务器没收到,那么服务器在超时后将重发第三次握手的FIN包,客户端接到重发的FIN包后可以再发一个ACK应答包。
- TCP建立连接可以两次握手吗?为什么?
- 客户端发送一个FIN段,并包含一个希望接收者看到的自己当前的序列号K. 同时还包含一个ACK表示确认对方最近一次发过来的数据。
- 服务端将K值加1作为ACK序号值,表明收到了上一个包。这时上层的应用程序会被告知另一端发起了关闭操作,通常这将引起应用程序发起自己的关闭操作。
- 服务端发起自己的FIN段,ACK=K+1, Seq=L
- 客户端确认。ACK=L+1
11 UDP
- UDP 缺乏可靠性。UDP 本身不提供确认,序列号,超时重传等机制。UDP 数据报可能在网络中被复制,被重新排序。即 UDP 不保证数据报会到达其最终目的地,也不保证各个数据报的先后顺序,也不保证每个数据报只到达一次
- UDP 数据报是有长度的。每个 UDP 数据报都有长度,如果一个数据报正确地到达目的地,那么该数据报的长度将随数据一起传递给接收方。而 TCP 是一个字节流协议,没有任何(协议上的)记录边界。
- UDP 是无连接的。UDP 客户和服务器之前不必存在长期的关系。UDP 发送数据报之前也不需要经过握手创建连接的过程。
- UDP 支持多播和广播。
- UDP没有TCP的接收确认、窗口等机制,因此在收发数据之前也不需要交换控制信息,也就是说不需要建立和断开连接的步骤,只要在从应用程序获取的数据前面加上UDP头部,然后交给IP进行发送就可以了
接收也很简单,只要根据IP头部中的接收方和发送方IP地址,以及UDP头部中的接收方和发送方端口号,找到相应的套接字并将数据交给相应的应用程序就可以了
12 访问的网站是如何切到https的
一种是原始的302跳转,服务器把所有的HTTP流量跳转到HTTPS。但这样有一个漏洞,就是中间人可能在第一次访问站点的时候就劫持。 解决方法是引入HSTS机制,用户浏览器在访问站点的时候强制使用HTTPS。
13 SYN攻击
在三次握手过程中,服务器发送 SYN-ACK 之后,收到客户端的 ACK 之前的 TCP 连接称为半连接(half-open connect)。此时服务器处于 SYN_RCVD 状态。当收到 ACK 后,服务器才能转入 ESTABLISHED 状态.SYN 攻击指的是,攻击客户端在短时间内伪造大量不存在的IP地址,向服务器不断地发送SYN包,服务器回复确认包,并等待客户的确认。由于源地址是不存在的,
服务器需要不断的重发直至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,导致目标系统运行缓慢,严重者会引起网络堵塞甚至系统瘫痪。- 如何检测 SYN 攻击?
- 检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的 netstats 命令来检测 SYN 攻击。
如何防御 SYN 攻击?
TCP全称传输控制协议,它是基于IP提供的寻址和路由服务而建立起来的负责实现端到端可靠传输的协议,之所以将TCP称为可靠的传输协议是因为TCP向调用者承诺了三件事情:
http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
- http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的
31 http1.0有哪些痛点
- 连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对文件类大请求影响较大。
- 解决方案:
- HTTP持久连接:Connection:Keep-Alive HTTP持久连接,痛点在于当前请求必须彻底完成后,下一请求才能正确发送。
- http long-polling:长轮询
- http streaming:建立起一个tcp连接后,服务器不会结束streaming请求,持续的通过这个通道返回最新的业务数据,数据通道也是单向的,除非客户端自动断开,否则一直保持连接
- websocket:也是基于tcp协议,提供双向的数据通道,优势在于提供了message的概念,同时又提供了传统的http所缺少的长连接功能
16 HTTP/2 有哪些缺陷?HTTP/3 做了哪些优化?
- 多个 HTTP 请求在复用一个 TCP 连接,下层的 TCP 协议是不知道有多少个 HTTP 请求的。一旦发生了丢包现象,就会触发 TCP 的重传机制,这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这个丢了的包被重传回来。
- HTTP/1.1 中的管道( pipeline)传输中如果有一个请求阻塞了,那么队列后请求也统统被阻塞住了
- HTTP/2 多请求复用一个TCP连接,一旦发生丢包,就会阻塞住所有的 HTTP 请求。
- 这都是基于 TCP 传输层的问题,所以 HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP!
19 TCP如何实现流量控制?
- 使用滑动窗口协议实现流量控制。防止发送方发送速率太快,接收方缓存区不够导致溢出。接收方会维护一个接收窗口 receiver window(窗口大小单位是字节),接受窗口的大小是根据自己的资源情况动态调整的,在返回ACK时将接受窗口大小放在TCP报文中的窗口字段告知发送方。发送窗口的大小不能超过接受窗口的大小,只有当发送方发送并收到确认之后,才能将发送窗口右移。发送窗口的上限为接受窗口和拥塞窗口中的较小值。接受窗口表明了接收方的接收能力,拥塞窗口表明了网络的传送能力。
20 什么是零窗口(接收窗口为0时会怎样)?
如果接收方没有能力接收数据,就会将接收窗口设置为0,这时发送方必须暂停发送数据,但是会启动一个持续计时器(persistence timer),到期后发送一个大小为1字节的探测数据包,以查看接收窗口状态。如果接收方能够接收数据,就会在返回的报文中更新接收窗口大小,恢复数据传送。
21 浏览器在与服务器建立了一个 TCP 连接后是否会在一个 HTTP 请求完成后断开?什么情况下会断开?
在 HTTP/1.0 中,一个服务器在发送完一个 HTTP 响应后,会断开 TCP 链接。HTTP/1.1 就把 Connection 头写进标准,并且默认开启持久连接,除非请求中写明 Connection: close,那么浏览器和服务器之间是会维持一段时间的 TCP 连接,不会一个请求结束就断掉。
23 一个 TCP 连接中 HTTP 请求发送可以一起发送么
在 HTTP/1.1 存在 Pipelining 技术可以完成这个多个请求同时发送,但是由于浏览器默认关闭,所以可以认为这是不可行的。在 HTTP2 中由于 Multiplexing 特点的存在,多个 HTTP 请求可以在同一个 TCP 连接中并行进行。
24 HTTP/1.1 时代,浏览器是如何提高页面加载效率的
维持和服务器已经建立的 TCP 连接,在同一连接上顺序处理多个请求。
-
25 DNS解析
在用chrome浏览器的时候,会先去浏览器的dns缓存里头查询,dns缓存中没有,再去调用gethostbyname函数(操作系统某个库,这个函数通过网卡给DNS服务器发UDP请求,接收结果,然后将结果给返回给浏览器。)
- 解析流程就是分级查询
- 先在本机的DNS里头查,如果有就直接返回了
- 本机DNS里头发现没有,就去根服务器里查。根服务器发现这个域名是属于com域,因此根域DNS服务器会返回它所管理的com域中的DNS 服务器的IP地址,意思是“虽然我不知道你要查的那个域名的地址,但你可以去com域问问看”
为什么既使用TCP又使用UDP?
因为UDP快啊!UDP的DNS协议只要一个请求、一个应答就好了。而使用基于TCP的DNS协议要三次握手、发送数据以及应答、四次挥手。但是UDP协议传输内容不能超过512字节。不过客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。
27 区域传送时使用TCP
辅域名服务器会定时(一般时3小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,则会执行一次区域传送,进行数据同步。区域传送将使用TCP而不是UDP,因为数据同步传送的数据量比一个请求和应答的数据量要多得多。
- TCP是一种可靠的连接,保证了数据的准确性。
28 网络的性能指标有哪些
- 通常是以4个指标来衡量网络的性能,分别是带宽、延时、吞吐率、PPS(Packet Per Second),它们表示的意义如下:
- 带宽,表示链路的最大传输速率,单位是
b/s
(比特 / 秒),带宽越大,其传输能力就越强。 - 延时,表示请求数据包发送后,收到对端响应,所需要的时间延迟。不同的场景有着不同的含义,比如可以表示建立
TCP
连接所需的时间延迟,或一个数据包往返所需的时间延迟。 - 吞吐率,表示单位时间内成功传输的数据量,单位是
b/s
(比特 / 秒)或者B/s
(字节 / 秒),吞吐受带宽限制,带宽越大,吞吐率的上限才可能越高。 PPS
,全称是Packet Per Second
(包 / 秒),表示以网络包为单位的传输速率,一般用来评估系统对于网络的转发能力。
- 带宽,表示链路的最大传输速率,单位是
当然,除了以上这四种基本的指标,还有一些其他常用的性能指标,比如:
33 Client如何实现长连接
TCP 协议的 KeepAlive 机制与 HeartBeat 心跳包
- HeartBeat心跳包
- 很多应用层协议都有 HeartBeat 机制,通常是客户端每隔一小段时间向服务器发送一个数据包,通知服务器自己仍然在线,并传输一些可能必要的数据。使用心跳包的典型协议是 IM,比如 QQ/MSN/飞信等协议。
- 心跳包之所以叫心跳包是因为:它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着。事实上这是为了保持长连接,至于这个包的内容,是没有什么特别规定的,不过一般都是很小的包,或者只包含包头的一个空包。
- 在 TCP 的机制里面,本身是存在有心跳包的机制的,也就是 TCP 的选项:SO_KEEPALIVE。系统默认是设置的 2 小时的心跳频率。但是它检查不到机器断电、网线拔出、防火墙这些断线。而且逻辑层处理断线可能也不是那么好处理。一般,如果只是用于保活还是可以的。
- 心跳包一般来说都是在逻辑层发送空的 echo 包来实现的。下一个定时器,在一定时间间隔下发送一个空包给客户端,然后客户端反馈一个同样的空包回来,服务器如果在一定时间内收不到客户端发送过来的反馈包,那就只有认定说掉线了。
- 其实,要判定掉线,只需要 send 或者 recv 一下,如果结果为零,则为掉线。但是,在长连接下,有可能很长一段时间都没有数据往来。
- 理论上说,这个连接是一直保持连接的,但是实际情况中,如果中间节点出现什么故障是难以知道的。更要命的是,有的节点(防火墙)会自动把一定时间之内没有数据交互的连接给断掉。在这个时候,就需要我们的心跳包了,用于维持长连接,保活。
- 在获知了断线之后,服务器逻辑可能需要做一些事情,比如断线后的数据清理呀,重新连接呀……当然,这个自然是要由逻辑层根据需求去做了。
- 总的来说,心跳包主要也就是用于长连接的保活和断线处理。一般的应用下,判定时间在 30-40 秒比较不错。如果实在要求高,那就在 6-9 秒。
TCP协议的
KeepAlive
机制- TCP 的 IP 传输层的两个主要协议是 UDP 和 TCP,其中 UDP 是无连接的、面向 packet 的,而 TCP 协议是有连接、面向流的协议。
- TCP 的 KeepAlive 机制,首先它貌似默认是不打开的,要用 setsockopt 将 SOL_SOCKET.SO_KEEPALIVE 设置为 1 才是打开,并且可以设置三个参数 tcp_keepalive_time/tcp_keepalive_probes/tcp_keepalive_intvl,分别表示连接闲置多久开始发 keepalive 的 ack 包、发几个 ack 包不回复才当对方死了、两个 ack 包之间间隔多.
- 于是连接就了有一个超时时间窗口,如果连接之间没有通信,这个时间窗口会逐渐减小,当它减小到零的时候,TCP 协议会向对方发一个带有ACK 标志的空数据包(KeepAlive 探针),对方在收到 ACK 包以后,如果连接一切正常,应该回复一个 ACK;如果连接出现错误了(例如对方重启了,连接状态丢失),则应当回复一个 RST;如果对方没有回复,服务器每隔 intvl 的时间再发 ACK,如果连续 probes 个包都被无视了,说明连接被断开了。
- 在 http 早期,每个 http 请求都要求打开一个 tpc socket 连接,并且使用一次之后就断开这个 tcp 连接。
- 使用 keep-alive 可以改善这种状态,即在一次 TCP 连接中可以持续发送多份数据而不会断开连接。通过使用 keep-alive 机制,可以减少 tcp 连接建立次数,也意味着可以减少 TIME_WAIT 状态连接,以此提高性能和提高 httpd 服务器的吞吐率 (更少的 tcp 连接意味着更少的系统内核调用, socket 的 accept() 和 close() 调用)。
- 但是,keep-alive 并不是免费的午餐, 长时间的 tcp 连接容易导致系统资源无效占用。配置不当的 keep-alive,有时比重复利用连接带来的损失还更大。所以,正确地设置 keep-alive timeout 时间非常重要。
- 使用 http keep-alvie,可以减少服务端 TIME_WAIT 数量 (因为由服务端 httpd 守护进程主动关闭连接)。道理很简单,相较而言,启用 keep-alive,建立的 tcp 连接更少了,自然要被关闭的 tcp 连接也相应更少了。
34 http能不能一次连接多次请求,不等后端返回
发送请求,接写入tcp缓冲,是可以多次进行的,这也是http是无状态的原因
35 HTTP2.0和HTTP1.X相比的新特性
多路复用:HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。
- 头部数据压缩:HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。
- 服务器推送: 为了改善延迟,HTTP2.0引入了server push,它允许服务端在浏览器明确地请求之前推送资源给浏览器,免得客户端再次创建连接发送请求到服务器端获取。这样客户端可以直接从本地加载这些资源,不用再通过网络。