网络篇
WARNING
本文取自 小林coding、JavaGuide和 🐔鸡翅老哥
一切为了方便自己背诵, 于是摘要过来
说一下TCP/IP的四层网络模型
TCP/IP 四层模型简化了 OSI 七层模型,专专注于实际的网络通信实现。每层都有其特定的功能和协议,通过这些层次的协作,实现了复杂的网络通信任务。
- 网络接口层:处理物理网络上的数据传输,
- 网络层:负责数据包的路由和网络间通信。
- 传输层:提供端到端的数据传输服务,确保数据的可靠性和完整性
- 应用层:为应用程序提供通信服务,处理高层协议和数据格式。
七层网络模型是什么
OSI模型把网络通信的工作分为7层, 分别是物理层, 数据链路层, 网络层, 传输层, 会话层, 表示层 和 应用层. 用于描述和标准化计算机网络通信的功能, 每一层都有特定的功能和协议
- 物理层:处理物理媒体上的数据传输,
- 数据链路层:提供点到点的数据传输和错误检测。(协议: PPP. ARP, Ethernet以太网)
- 网络层:负责数据包的路由和网络间通信。(协议: IP, ICMP, IGMP, OSPF, BGP)
- 传输层:提供端到端的数据传输服务,确保数据的可靠性和完整性(协议: TCP, UDP)
- 会话层:管理应用程序之间的会话。(协议: RPC)
- 表示层:处理数据的格式化、加密和解密(JPEG, GIF, MPEG数据格式)
- 应用层:为应用程序提供通信接口和服务。(协议: HTTP, HTTPS, FTP, SFTP, SMTP, POP3/IMAP, DNS, SSH)
OSI分层的好处有哪些
标准化通信协议:
通过定义标准的通信协议, 各种不同的软硬件供应商可以开发互操作的网络设备和应用程序;
公用一套标准化的协议,新旧设备之间互相兼容
模块化设计:
每一层可以独立开发和优化, 使得专注于本层的功能, 无需关注起他层的实现, 层与层之间可以独立的修改和升级,不会影响到其他层
故障隔离和诊断
通过分层结构可以更容易地定位到网络问题的具体层次, 从而针对该层次的问题对症下药, 也更有条理
简化网络设计和维护
每一层都有自己明确的职责和功能, 分层结构十分清晰和明确,便于教学
增强网络安全
可以在每一层上实施不同的安全措施
提高网络性能
通过在不同层次上的优化可以提高整体性能;
分层结构可以更容易地实现负载均衡和流量管理, 提高网络的效率和可靠性
如果建立连接后,客户端突然故障怎么办
TCP Keepalive机制
TCP协议本身没有直接的机制来检测对端是否故障,但可以通过以下方式来处理这种情况:
- TCP Keepalive : TCP Keepalive是一种可选的机制,用于检测连接的对端是否仍然存在。 如果启用了TCP Keepalive,服务器会定期发送探测包(Keepalive探测)到客户端。 如果在一定时间内没有收到客户端的响应,服务器会认为客户端已经不可达,并关闭连接。
- 应用层心跳机制: 应用层可以实现自己的心跳机制,通过定期发送心跳消息来检测对端是否仍然存在。 如果在一定时间内没有收到心跳响应,服务器可以认为客户端已经故障,并采取相应措施。
TCP超时和重传机制
TCP协议有自己的超时和重传机制,这些机制可以帮助检测连接是否已经断开:
- 重传超时(RTO) TCP会为每个发送的数据包设置一个重传超时(RTO) 如果在RTO时间内没有收到对端的确认,TCP会重传数据包, 如果多次重传仍然没有收到确认,TCP会认为连接已经断开
- 窗口探测(Zero Window Probe): 如果对端的接收窗口为零(表示对端暂时无法接收数据),TCP会定期发送窗口探测包。 如果在一定时间内没有收到对端的响应,TCP会认为连接已经断开。
常见的HTTP状态码有哪些
1xx: 信息性响应
100 Continue: 客户端应继续其请求
2xx: 成功
200 OK 请求成功且服务器返回了请求的资源
201 Created 请求成功并且服务器创建了新资源
202 Accepted 请求已接受但尚未处理完成
204 No Content 请求成功但是没有内容返回
3xx: 重定向(表示客户端请求的资源发生了变动,需要客户端用新的URL重新发送请求获取资源)
301 Moved Permanently 请求的资源已经永久移动到新的URL(永久重定向)
302 Found 临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。
4xx: 客户端发送的报文有误,服务器无法处理
400 Bad Request 请求无效或者格式错误
401 Unauthorized 请求需要身份验证
403 Forbidden 服务器拒绝请求,客户端无权限
404 Not Found 请求资源不存在(无法找到此页面)
405 Method Not Allowed 请求的方法类型不支持
5xx: 服务器内部错误
500 Internal Server Error 服务器内部错误
502 Bad Gateway 服务器作为网关或代理, 从上游服务器收到无效的响应
504 Gateway Time-out 作为网关或者代理工作的服务器尝试执行请求时,未能 及时 从上游服务器收到响应。
举一个例子,假设 nginx 是代理服务器,收到客户端的请求后,将请求转发到后端服务器i(tomcat等) 当nginx收到了无效的响应时,就返回502。 当nginx超过自己配置的超时时间,还没有收到请求时,就返回504错误。
请求转发 Forward 和 重定向 Redirect 有啥区别
请求转发是服务器内部的请求转发, 服务器接收到客户端的请求以后将请求转发给另一个资源进行处理, 而 客户端并不知道这一过程
特点:
- URL不变
- 请求和相应对象在服务器内部传递, 不会发送新的HTTP请求
- 原始请求和响应对象可以在转发的资源之间共享, 能够直接访问请求中的数据
适用于在同一个Web应用内部的资源之间转发请求; 需要在多个资源之间共享请求数据时
重定向是客户端重定向. 服务器收到客户端请求以后 发送一个重定向响应(HTTP状态码302或者其他) 和 新的URL 给客户端, 客户端浏览器会 自动 发起对新的URL的请求
特点:
- URL改变为新的URL
- 服务器发送重定向响应后客户端发起一个新的HTTP请求
- 请求数据不会自动传递, 需要通过URL参数或者其他方式传递
适用需要通知客户端浏览器进行新请求的情况, 比如跳转到外部资源 或者 不同的WEB应用
HTTP层请求的类型有哪些
- GET:用于请求获取指定资源,通常用于获取数据。
- POST:用于向服务器提交数据,通常用于提交表单数据或进行资源的创建
- PUT:用于向服务器更新指定资源,通常用于更新已存在的资源。
- DELETE:用于请求服务器删除指定资源。
- HEAD: 类似于GET请求,但只返回资源的头部信息,用于获取资源的元数据而不获取实际内容。
GET和POST的区别和使用场景
从小林那边获取的听起来比较官方的说法:
根据 RFC 规范,GET 的语义是从服务器获取指定的资源,这个资源可以是静态的文本、页面、图片视频等。GET 请求的参数位置一般是写在 URL 中,URL 规定只能支持 ASCI,所以 GET 请求的参数只允许ASCI 字符 ,而且浏览器会对 URL 的长度有限制(HTTP协议本身对 URL长度并没有做任何规定)
根据 RFC 规范,POST 的语义是根据请求负荷(报文body)对指定的资源做出处理,具体的处理方式视资源类型而不同。POST请求携带数据的位置一般是写在报文 body 中,body 中的数据可以是任意格式的数据,只要客户端与服务端协商好即可,而且浏览器不会对 body 大小做限制。
如果从 RFC 规范定义的语义来看:
GET 方法就是安全且幂等的,因为它是「只读」操作,无论操作多少次,服务器上的数据都是安全的且每次的结果都是相同的。所以,可以对 GET 请求的数据做缓存,这个缓存可以做到浏览器本身上(彻底避免浏览器发请求),也可以做到代理上(如nginx),而且在浏览器中 GET 请求可以保存为书签
POST 因为是「新增或提交数据」的操作,会修改服务器上的资源,所以是不安全的,且多次提交数据就会创建多个资源,所以不是幂等的。所以,浏览器一般不会缓存 POST 请求,也不能把 POST 请求保存为书签。
但是实际过程中,开发者不一定会按照 RFC 规范定义的语义来实现 GET 和 POST 方法。比如:
可以用 GET方法实现新增或删除数据的请求,这样实现的 GET 方法自然就不是安全和幂等
可以用 POST 方法实现查询数据的请求,这样实现的 POST 方法自然就是安全和幂等。
- 用途和语义 GET:用于请求从服务器获取数据。是幂等的(多次相同请求不会改变资源状态)。常用于获取资源,如网页、图片等。 POST:用于向服务器发送数据以创建或更新资源。不是等的(多次相同请求可能会导致不同的结果)。常用于提交表单数据、上传文件等。
- 数据传输方式 GET:数据通过URL传递,包括在查询字符串中(URL的一部分)。示例:
http://example.com/page?param1=value1¶m2=value2
URL长度有限制(具体限制取决于浏览器和服务器)。 POST:数据通过HTTP请求体传递。示例:在请求体中以键值对形式传递数据。没有明显的长度限制(限制取决于服务器配置)。 - 安全性 GET:数据在URL中明文传输,容易被缓存和记录。不适合传输敏感信息(如密码) POST:数据在请求体中传输,不会显示在URL中。更适合传输敏感信息,但仍需通过HTTPS加密以确保安全
- 可见性和缓存 GET:数据在URL中,用户和浏览器历史记录中可见。通常会被浏览器缓存。可以通过书签保存 POST:数据不在URL中,不会在浏览器历史记录中显示。默认不会被浏览器缓存。不适合通过书签保存
- ldempotency(幂等性) GET:冥等的,多次请求不会改变资源状态。 POST:不是篡等的,多次请求可能会导致资源状态变化(如多次提交表单)。
- 适用场景 GET:获取资源或数据。传递少量非敏感数据。请求可以被缓存和书签保存的场景。 POST:提交表单数据。上传文件。传递大量数据或敏感信息。需要对请求进行处理或改变服务器状态的场景
说一下TCP的头部
序列号:在建立连接时由计算机生成的随机数作为其初始值,通过 SYN 包传给接收端主机,每发送一次数据,就「累加」一次该「数据字节数」的大小。用来解决网络包乱序问题。
确认应答号:指下一次「期望」收到的数据的序列号,发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。用来解决丢包的问题
控制位:
- ACK:该位为1时,「确认应答」的字段变为有效,TCP规定除了最初建立连接时的 SYN 包之外该位必须设置为1。
- RST:该位为1时,表示 TCP 连接中出现异常必须强制断开连接。
- SYN:该位为1时,表示希望建立连接,并在其「序列号」的字段进行序列号初始值的设定
- FIN:该位为1时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换 FIN 位为 1的 TCP 段。
TCP三次握手和四次挥手
总结
三次握手 :确保客户端和服务器双方都知道对方的接收和发送能力, 建立可靠的传输连接
四次挥手 :确保 双方都能完成 数据传输, 并 有序地 终止连接, 确保所有数据都被正确接收
具体过程
三次握手(建立连接)
一开始,客户端和服务端都处于 CLOSE
状态。先是服务端主动监听某个端口,处于 LSTEN 状态
第一次握手(SYN):
客户端会随机初始化序号(client_isn),将此序号置于 TCP 首部的「序列号」字段中,同时把 SYN 标志位置为 1,表示 SYN 报文。
接着把第一个 SYN 报文发送给服务端,表示向服务端发起连接(请求建立连接),该报文不包含应用层数据,之后客户端处于 SYN-SENT 状态。
第二次握手(SYN-ACK)
服务端收到客户端的 SYN 报文后,首先服务端 也随机初始化自己的序号(server_isn),将此序号填入TCP 首部的「序列号」字段中,其次把 TCP 首部的「确认应答号」字段填入 client isn +1
接着把 SYN和 ACK 标志位置为 1。最后把该报文(SYN-ACK报文)发给客户端,该报文也不包含应用层数据,之后服务端处于 SYN-RCVD 状态。
第三次握手(ACK)
客户端收到服务端报文后,还要向服务端 回应最后一个应答报文
首先该应答报文 TCP 首部 ACK 标志位置为1,其次「确认应答号」字段填入 server_isn +1,
最后把报文发送给服务端,但是这次报文可以携带客户到服务端的数据,之后客户端处于 ESTABLISHED 状态。
服务端收到客户端的应答报文后,也进入 ESTABLISHED 状态。
经过三次握手,客户端和服务器之间的连接正式建立,可以开始传输数据。
第三次握手是可以携带数据的,前两次握手是不可以携带数据的,这也是面试常问的题。
四次挥手(终止连接)
第一次挥手(FIN) 客户端向服务器发送一个FIN(终止连接)报文段,表示客户端不再发送数据,但仍可以接收数据。客户端进入 FIN_WAIT_1 状态 报文段中包含一个序列号(Seq=u)。
第二次挥手(ACK) 服务器收到FIN报文后,向客户端发送一个ACK报文段,确认收到客户端的FIN报文。服务端进入CLOSE_WAIT状态
在收到 FIN 报文的时候,TCP 协议栈会为 FIN 包插入一个文件结束符 EOF 到接收缓冲区中,服务端应用程序可以通过 read 调用来感知这个 FIN 包,这个 EOF 会被放在已排队等候的其他已接收的数据之后,所以必须要得继续 read 接收缓冲区已接收的数据
该报文段包含确认号(Ack=u+1)。
第三次挥手(FIN):
接着,当服务端在 read 数据的时候,最后 自然就会读到 EOF,接着 read() 就会返回 0,这时服务端应用程序如果有数据要发送的话,就发完数据后才调用关闭连接的函数,如果服务端应用程序没有数据要发送的话,可以直接调用关闭连接的函数
这时服务端就会发一个 FIN 包,这个 FIN 报文代表服务端不会再发送数据了,之后处于 LAST_ACK 状态
第四次挥手(ACK)
客户端接收到服务端的 FIN 包,并发送 ACK 确认包给服务端,此时客户端将进入 TIME_WAIT 状态
服务端收到 ACK 确认包后,就进入了最后的 CLOSE 状态
客户端经过 2MSL 时间之后,也进入 CLOSE 状态;
INFO
MSL 代表 Maximum Segment Lifetime,即报文段的最大存活时间,是网络中一个 TCP 报文段可能存活的最长时间。超过这个时间报文段就会被丢弃。
经过四次挥手客户端和服务器之间的连接正式终止
TCP两次握手不可以吗
三次握手的设计是确保 双方都能正确的接受和发送数据, 并且可以处理网络中的各种不可靠因素, 如果只是用两次握手, 可能会导致一些问题.
三次握手的过程(详细看上面的TCP三次握手四次挥手)
第一次握手(SYN):
客户端发送 一个SYN包给服务器, 请求建立连接,客户端进入SYS_SENT状态(说明客户端可以发送消息)
第二次握手(SYN-ACK):
服务器收到 一个SYN包以后, 服务器发送 一个SYN-ACK包给客户端, 表示同意建立连接, 并确认客户端的SYN包,服务器进入SYN-RCVD状态(说明服务器可接收 可发送)
第三次握手(ACK):
客户端收到 一个SYN-ACK包以后, 发送一个ACK包给服务器, 确认服务器的的SYN-ACK包, 客户端和服务器都进入ESTABLISHED状态, 连接建立完成
两次握手的问题
如果只使用两次握手,可能会导致以下问题:
- 旧的重复连接请求: 假设一个旧的SYN包在网络中延迟了很长时间,最终到达服务器。服务器会认为这是一个新的连接请求并发送SYN-ACK包。 如果没有第三次握手,服务器会认为连接已经建立,但客户端可能根本没有发起这个连接请求,导致服务器资源被浪费
- 确认数据传输的可靠性 三次握手确保双方都能接收和发送数据。第一次握手确认客户端能发送,第二次握手确认服务器能接收并发送,第三次握手确认客户端能接收。 两次握手无法确认客户端是否能正确接收服务器的数据,可能导致数据传输的不可靠。
为什么tcp连接是3次,关闭是4次?
数据传输的完整性:关闭连接时,需要 确保所有数据都已传输完毕,因此需要额外的确认步骤。
半关闭状态:TCP允许连接的一方在发送完数据后立即关闭发送通道,但仍然可以接收数据、这种半关闭状态需要额外的步骤来确认。
TIME_WAIT状态:为了确保对方收到最后的ACK包,并防止旧的重复数据包干扰新的连接,发送最后一个ACK的一方进入TIME_ WAIT状态。
TCP如何保证可靠性
- 三次握手(Three-Way Handshake) 在建立连接时,TCP使用三次握手来确保双方都准备好进行通信。过程如下: i.客户端发送一个SYN(同步)包到服务器,表示请求建立连接。 ii.服务器收到SYN包后,回复一个SYN-ACK(同步-确认)包,表示同意建立连接。 iii.客户端收到SYN-ACK包后,发送一个ACK(确认)包,表示连接建立成功。
- 序列号和确认机制(Sequence Numbers and Acknowledgments): 每个TCP段(数据包)都有一个序列号,接收方使用该序列号来重组数据并检测丢失的包。接收方在收到数据后,会发送一个ACK(确认)包,告知发送方已成功接收的数据序列号如果发送方在一定时间内没有收到ACK包,会重传该数据包。
- 重传机制(Retransmission Mechanism)TCP使用超时重传机制,如果发送方在超时时间内没有收到ACK包,会重传该数据包,TCP还使用快速重传机制,当接收方检测到数据包丢失时,会立即通知发送方进行重传,而不必等待超时。
- 流量控制(Flow Control)使用滑动窗口机制来控制数据流量,确保发送方不会发送超过接收方处理能力的数据量,滑动窗口大小由接收方在ACK包中告知发送方,发送方根据窗口大小调整发送速率。
- 拥塞控制(Congestion Control)4.TCP使用多种算法(如启动、拥塞避免、快速重传和快速恢复)来检测和避免网络拥塞。这些算法通过调整发送速率,防止网络过载,从而减少数据包丢失和延迟,数据校验和(Checksum)
- 每个TCP段都包含一个校验和字段,用于检测数据在传输过程中是否被损坏。 接收方计算接收到的数据的校验和并与发送方的校验和进行比较,如果不匹配,则认为数据损坏并丢弃该段。
说说HTTP、TCP、Socket 的关系是什么
Socket(套接字)
Socket 是一种编程接口,用于在网络上进行通信。它抽象了网络通信的底层细节,使得程序员可以通过简单的接口进行网络通信。
Socket 可以基于不同的传输协议,如 TCP 和 UDP。常见的 Socket 类型包括流式套接字(基于 TCP)和数据报套接字(基于 UDP)。
在使用 HTTP 进行通信时,客户端和服务器会创建 TCP Socket,通过这些 Socket 进行连接和数据传输。
关系总结
- HTTP是应用层 协议,用于 定义 客户端和服务器之间的 请求和响应格式。
- TCP是传输层 协议,提供可靠的、面向连接的通信服务,HTTP 依赖 TCP 来传输数据
- Socket是 编程接口,抽象了网络通信的底层细节,应用程序通过 Socket 进行网络通信,使用 TCP 或 UDP作为传输协议。
HTTP进行TCP连接之后,在什么情况下会中断
当 服务端或者客户端 执行 close 系统调用 的时候,会 发送FIN报文,就会 进行四次挥手的过程
当发送方发送了数据之后,接收方 超过一段时间没有响应ACK报文,发送方 重传数据达到最大次数 的时候,就会断开TCP连接
当HTTP长时间没有进行请求和响应的时候,超过一定的时间,就会释放连接
HTTP 和 HTTPS 有什么区别?
HTTP 和 HTTPS 对比
- 端口号:HTTP 默认是 80,HTTPS 默认是 443。
- URL 前缀:HTTP 的 URL 前缀是
http://
,HTTPS 的 URL 前缀是https://
。 - 安全性和资源消耗:HTTP 协议运行在 TCP 之上,所有 传输的内容都是明文,客户端和服务器端都无法验证对方的身份。HTTPS 是运行在 SSL/TLS 之上的 HTTP 协议,SSL/TLS 运行在 TCP 之上。所有 传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。所以说,HTTP 安全性没有 HTTPS 高,但是 HTTPS 比 HTTP 耗费更多服务器资源。
- HTTP建立连接比较简单,TCP 三次握手之后就可以 HTTP 报文传输,而HTTPS 在 TCP 三次握手之后,还需要进行 SSL/TLS 的握手过程,才可进入加密的报文传输
- SEO(搜索引擎优化):搜索引擎通常会更青睐使用 HTTPS 协议的网站,因为 HTTPS 能够提供更高的安全性和用户隐私保护。使用 HTTPS 协议的网站在搜索结果中可能会被优先显示,从而对 SEO 产生影响。
关于HTTPS的握手过程,跳转至小林coding
HTTP1.1怎么对请求做拆包,具体来说怎么拆
在HTTP/1.1中,请求的拆包是通过"Content-Length"头字段来进行的。该字段指示了请求正文的长度,服务器可以根据该长度来正确接收和解析请求。
具体来说,当客户端发送一个HTTP请求时,会在请求头中添加"Content-Length"字段,该字段的值表示请求正文的字节数。
服务器在接收到请求后,会根据"Content-Length"字段的值来确定请求的长度,并从请求中读取相应数量的字节,直到读取完整个请求内容。
这种基于"Content-Length"字段的拆包机制可以确保服务器正确接收到完整的请求,避免了请求的丢失或截断问题。
Http1.1和2.0的区别是什么?
HTTP/2 相比 HTTP/1.1 性能上的改进,
头部压缩:HTTP/2 会压缩头(Header)如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会帮你消除重复的部分。这就是所谓的 HPACK 算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。
进制格式:HTTP/2 不再像 HTTP/1.1 里的 纯文本 形式的报文,而是 全面采用了二进制格式,头信息和数据体都是二进制,并且统称为帧(frame):头信息帧(Headers Frame)和数据帧(DataFrame)。 这样虽然对人不友好,但是对计算机非常友好,因为计算机只懂二进制,那么收到报文后 无需再将明文的报文转成二进制,而是直接解析二进制报文,这增加了数据传输的效率。
并发传输:引出了 ** Stream** 概念,多个 Stream ** 复用在一条 TCP 连接**。解决了HTTP/1.1 队头阻塞的问题:
服务器主动推送资源:HTTP/2 还在一定程度上改善了传统的「请求-应答」工作模式, 服务端不再是被动地响应,可以主动向客户端发送消息
HTTP长连接与WebSocket有什么区别?
- 全双工和半双工:TCP 协议本身是全双工的,但我们最常用的 HTTP/1.1,虽然是基于 TCP 的协议,但它是半双工的,对于大部分需要服务器主动推送数据到客户端的场景,都不太友好,因此我们需要使用支持全双工的 Websocket 协议。
- 应用场景区别:在 HTTP/1.1 里,只要客户端不问,服务端就不答(即半双工)。基于这样的特点,对于登录页面这样的简单场景,可以使用定时轮询或者长轮询的方式实现服务器推送(comet)的效果。对于客户端和服务端之间需要频繁交互的复杂场景,比如网页游戏,都可以考虑使用 WebSocket 协议。
HTTP 长连接 和 短连接 的区别
在回答这个问题之前,我们先解释一下为什么会有长连接和短链接,从它的源头将起:
HTTP 协议采用的是「请求-应答」的模式,也就是客户端发起了请求,服务端才会返回响应,一来一回
由于 HTTP 是基于 TCP 传输协议实现的,客户端与服务端要进行 HTTP 通信前,需要先建立 TCP 连接,然后客户端发送 HTTP 请求,服务端收到后就返回响应,至此「请求-应答」的模式就完成了,随后就会释放 TCP 连接。
如果每次请求都要经历 : 建立TCP -> 请求资源 -> 响应资源 -> 释放连接,那么就是短链接,如下图
显然这样太累,每次建立一个连接只能请求一次资源,于是出现了长连接
可以使用同一个 TCP 连接来发送和接收多个 HTTP 请求/应答,避免了连接建立和释放的开销
具体的可以看下面
短连接(HTTP/1.0 默认)
定义:短连接是一种在每次请求和响应之后立即关闭 TCP 连接的方式。
工作流程:
- 客户端发起一个 HTTP 请求
- b.服务器处理请求并发送响应。
- c.服务器关闭 TCP 连接。
- d.如果客户端需要再次请求数据,必须重新建立一个新的 TCP
连接优点:
- 实现简单。
- 资源释放及时。
缺点:
- 每次请求都需要重新建立和关闭 TCP 连接,增加了连接建立的开销(如三次握手和四次挥手),影响性能。
- 对服务器和网络的负担较大,尤其是在大量短时间请求的情况下
长连接(HTTP/1.1 默认)
定义:长连接是一种在多次请求和响应之间保持TCP连接打开的方式,允许复用同一个连接进行多个请求和响应。
HTTP 长连接的特点是,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态
工作流程:
- 客户端发起一个 HTTP 请求,并在请求头中包含 Connection:keep-alive(HTTP/1.1 默认即为长道接)。
- 服务器处理请求并发送响应,同时保持连接打开,
- 客户端可以在同一个连接上发送后续请求,服务器继续响应,
- 连接在一段时间内保持打开状态,直到客户端或服务器主动关闭连接,或超时关闭。
优点:
- 减少了连接建立和关闭的开销,提高了传输效率,
- 减少了网络和服务器的负担,适合频繁的请求和响应
缺点:
- 需要管理长时间保持的连接,增加了资源管理的复杂性,
- 可能会占用服务器资源,尤其是在大量长时间未关闭的连接情况下。
什么是跨域问题 如何解决
参考:https://blog.csdn.net/wanxingahlal/article/details/140529856
如何理解HTTP协议是无状态的
HTTP(HyperText Transfer Protocol)是无状态的协议,这意味着每个请求都是独立的,与之前或之后的请求没有直接关联。服务器不会自动保存客户端的状态信息。每次客户端向服务器发送请求时,服务器处理完请求后,不会保留任何关于该客户端的请求状态的信息。
无状态的具体含义
- 独立性: 每个 HTTP 请求都是独立的,服务器不会自动记住之前的请求信息。 每次请求都必须包含所有必要的信息,以便服务器能够理解和处理请求
- 简化服务器设计: 由于服务器不需要保存请求的状态信息,简化了服务器的设计和实现。 服务器不需要为每个客户端维护会话状态,减少了内存和资源的消耗。
无状态的优缺点
优点
- 简单性: 无状态协议使得服务器的设计和实现更加简单,因为不需要管理和维护客户端的状态。
- 可扩展性: 由于服务器不需要保存状态信息,可以轻松地横向扩展(通过增加更多服务器来分担负载)。
- 健壮性: 无状态协议提高了系统的健壮性,因为每个请求都是独立的,服务器之间不需要共享状态信息
缺点
- 需要重复传递信息: 由于每个请求都是独立的,客户端需要在每次请求中重复传递必要的状态信息(如认证信息、会话ID等)
- 客户端负担增加: 为了保持状态,客户端需要在每次请求中包含足够的状态信息,这增加了客户端的负担
说一下 TCP 粘包是怎么产生的?怎么解决粘包问题的?
TCP 粘包是指在使用 TCP 协议进行数据传输时,接收方在读取数据时无法正确区分出每个数据包的边界,导致多个数据包被粘在一起,或者一个数据包被拆分成多个部分。粘包和拆包问题主要是由于 TCP 协议的流式传输特性引起的。
TCP 粘包产生的原因
- 发送方原因: 发送方发送数据的速度快于接收方处理数据的速度,导致多个数据包被合并在一起发送。发送方调用 send 函数时,可能会将多个小数据包合并成一个大的数据包发送。
- 接收方原因: 接收方读取数据的速度快于发送方发送数据的速度,导致一个数据包被拆分成多个部分接收接收方调用 recv 函数时,可能会一次读取多个数据包,或者只读取一个数据包的一部分。
解决粘包问题的方法
解决粘包问题的关键是要在接收方正确地解析出每个数据包的边界。常见的解决方法包括以下几种:
- 定长消息 将每个消息的长度固定,这样接收方可以根据固定的长度来读取数据。
- 特殊分隔符 在每个消息的末尾添加特殊的分隔符,接收方可以根据分隔符来区分消息的边界
- 消息头部包含长度信息 在每个消息的头部添加一个固定长度的字段,用于表示消息的总长度。接收方首先读取消息头部,解析出消息的长度,然后根据长度读取完整的消息,
- 应用层协议 设计一个应用层协议,规定消息的格式和解析规则,使得接收方能够根据协议正确地解析出每个消息
Session, Cookie, Token的区别
- Session :服务器端存储用户会话状态,通过 Session ID 识别用户。适用于需要在服务器端保持用户状态的场景。
- Cookie :客户端存储少量数据,可以用于会话管理和用户偏好设置。安全性较低,需要注意保护敏感信息
- Token :客户端存储的身份验证字符串,常用于无状态的身份验证机制。适用于分布式系统和需要跨域的场景。
CDN 是什么
说明
CDN(Content Delivery Network,内容分发网络)是一种分布式的网络基础设施,旨在通过将内容分发到多个地理位置分散的服务器节点上,从而加快用户访问网站内容的速度,提高网站的可靠性和可用性。CDN 的主要功能是将静态内容(如图片、视频、JavaScript、CSS 文件等)缓存到离用户最近的服务器节点,从而减少网络延迟和带宽消耗。
CDN 的工作原理
1.内容缓存:网站的静态内容会被缓存到 CDN 的多个服务器节点上,这些节点通常称为边缘服务器(EdgeServers)。当用户第一次访问网站时,请求会被路由到最近的CDN 节点,该节点会从源服务器获取内容并缓存起来。
2.请求路由:当用户访问网站时,DNS 解析会将用户的请求路由到离用户最近的 CDN 边缘服务器。这样可以减少网络延迟,提高访问速度
3.内容分发:CDN 边缘服务器会根据用户的请求提供缓存的内容。如果某个边缘服务器没有缓存请求的内容它会从其他边缘服务器或源服务器获取内容并缓存。
4.负载均衡:CDN 使用负载均衡技术将用户请求分配到多个服务器,避免单个服务器过载,提高系统的可靠性和可用性。
CDN 的优势
1.提高访问速度:通过将内容缓存到离用户最近的服务器节点上,减少了数据传输的距离和网络延迟,从而加快了用户访问速度。
2.提高网站可用性:CDN 的分布式架构可以在某些服务器出现故障时,自动将请求路由到其他可用的服务器2提高网站的可靠性和可用性。
3.减轻源服务器负载:CDN 可以将大量的静态内容缓存到边缘服务器上,减少了源服务器的负载,提高了源服务器的性能。
4.节省带宽成本:通过缓存内容,CDN 可以减少源服务器的带宽消耗,从而降低带宽成本
5.抗 DDoS 攻击:CDN 的分布式架构和负载均衡技术可以有效防御分布式拒绝服务(DDoS)攻击,提高网站的安全性
CDN 的应用场景
1.网站加速:通过将网站的静态内容缓存到 CDN 节点上,提高用户访问网站的速度和体验
2.视频流媒体:CDN 可以将视频内容缓存到边缘服务器上,减少视频加载时间,提高视频播放的流畅度
3.软件分发:CDN 可以加速软件和补丁的下载,提高用户下载速度。
4.电子商务:CDN 可以提高电子商务网站的响应速度,提升用户购物体验。
5.全球内容分发:CDN 可以将内容分发到全球各地的服务器节点上,确保不同地区的用户都能快速访问内容
DNS的底层使用TCP还是UDP?
参考: https://blog.csdn.net/2201_75444658/article/details/140272157
DNS 的默认端口是53
DNS 基于 UDP协议 实现,DNS使用UDP协议进行域名解析和数据传输。因为基于UDP实现DNS能够提供低延迟、简单快速、轻量级的特性,更适合DNS这种需要快速响应的域名解析服务。
低延迟: UDP是一种无连接的协议,不需要在数据传输前建立连接,因此可以减少传输时延,适合DNS这种需要快速响应的应用场景。
简单快速: UDP相比于TCP更简单,没有TCP的连接管理和流量控制机制,传输效率更高,适合DNS这种需要快速传输数据的场景。
轻量级:UDP头部较小,占用较少的网络资源,对于小型请求和响应来说更加轻量级,适合DNS这种频繁且短小的数据交换,
尽管 UDP 存在丢包和数据包损坏的风险,但在 DNS 的设计中,这些风险是可以被容忍的。DNS 使用了些机制来提高可靠性,例如查询超时重传、请求重试、缓存等,以确保数据传输的可靠性和正确性。
HTTP到底是不是无状态的?
HTTP是无状态的,这意味着(或者说主要是因为)每个请求都是独立的,服务器不会在多个请求之间保留关于客户端状态的信息。在每个HTTP请求中,服务器不会记住之前的请求或会话状态,因此每个请求都是相互独立的。
虽然HTTP本身是无状态的,但可以 通过一些机制来实现状态保持(也就是说,严格地说本身是无状态的,但是可以达到记录状态的目的),其中最常见的方式是使用Cookie和Session来跟踪用户状态。通过在客户端存储会话信息或状态信息,服务器可以识别和跟踪特定用户的状态,以提供一定程度的状态保持功能。
tips: 虽然Cookie是HTTP协议簇的一部分,但是HTTP协议在 设计初衷 上仍然保持无状态特性,即每个请求都是相互独立的。使用Cookie只是在无状态协议下的一种 补充机制,用于在客户端存储状态信息以 实现状态保持
从输入URL到显示网页期间发生了什么
解析URL:分析 URL 所需要使用的传输协议和请求的资源路径。如果输入的 URL 中的协议或者主机名不合法,将会把地址栏中输入的内容传递给搜索引擎。如果没有问题,浏览器会检査 URL 中是否出现了非法字符,则对非法字符进行转义后在进行下一过程。
缓存判断:浏览器会判断所请求的资源是否在缓存里,如果请求的资源在缓存里且没有失效,那么就直接使用,否则向服务器发起新的请求。
DNS解析:如果资源不在本地缓存,首先需要进行DNS解析。浏览器会向本地DNS服务器发送域名解析请求,本地DNS服务器会逐级查询,最终找到对应的IP地址
获取MAC地址:当浏览器得到IP 地址后,数据传输还需要知道目的主机 MAC 地址,因为应用层下发数据给传输层,TCP 协议会指定源端口号和目的端口号,然后下发给网络层。网络层会将本机地址作为源地址,获取的 IP 地址作为目的地址。然后将下发给数据链路层,数据链路层的发送需要加入通信双方的 MAC 地址,本机的 MAC 地址作为源 MAC 地址,目的 MAC 地址需要分情况处理。通过将IP 地址与本机的子网掩码相结合,可以判断是否与请求主机在同一个子网里,如果在同一个子网里,可以使用 APR 协议获取到目的主机的 MAC地址,如果不在一个子网里,那么请求应该转发给网关,由它代头转发,此时同样可以通过 ARP 协议来获取网关的 MAC 地址,此时目的主机的 MAC 地址应该为网关的地址。
建立TCP连接:主机将使用目标IP地址和目标MAC地址发送一个TCP_SYN包,请求建立一个TCP连接然后交给路由器转发,等路由器转到目标服务器后,服务器回复一个SYN-ACK包,确认连接请求。然后,主机发送一个ACK包,确认已收到服务器的确认,然后TCP 连接建立
在HTTP/1.1版本中,默认情况下每个请求都会建立一个新的TCP连接;但在HTTP/2中,多个请求可以复用同一个TCP连接,这大大提高了网络效率。
完成HTTPS 的 TLS 四次握手:如果使用的是 HTTPS 协议,在通信前还存在 TLS 的四次握手
发送HTTP请求:连接建立后,浏览器会向服务器发送HTTP请求。请求中包含了用户需要获取的资源的信息,例如网页的URL、请求方法(GET、POST等)等
服务器处理请求并返回响应:服务器收到请求后,会根据请求的内容进行相应的处理。例如,如果是请求网页,服务器会读取相应的网页文件,并生成HTTP响应。
这个过程可能涉及文件系统操作、数据库查询等如果服务器设置了重定向(如301或302重定向),则会向浏览器发送重定向响应,告知浏览器新的URL地址。
浏览器解析并渲染页面:浏览器收到服务器的响应后,会解析HTML、CSS和JavaScript等文件,构建DOM树和渲染树。在解析过程中,浏览器可能会发现HTML文件中嵌入了其他资源(如图片、视频等),此时会发送额外的HTTP请求来获取这些资源。一旦所有资源都加载完成,浏览器就会渲染页面并显示在屏幕上
关闭TCP连接:在HTTP/1.0中,服务器发送完响应后通常会关闭TCP连接;但在HTTP/1.1和HTTP/2中,连接可能会被保持打开状态以支持多个请求的复用
HTTPS的加密是什么
说明
HTTPS(HyperText Transfer Protocol Secure)是HTTP的安全版本,用于在计算机网络上进行安全通信。HTTPS通过使用传输层安全(TLS,TransportLayerSecurity)协议来加密数据,从而保护通信的机密性和完整性。TLS是SSL(SecureSockets Layer)的后继版本。
HTTPS使用两种主要的加密算法:
- 对称加密: 对称加密使用相同的密钥进行加密和解密。常见的对称加密算法包括AES(Advanced Encryption Standard)、DES(Data EncryptionStandard)等。 对称加密速度快,适合大数据量的加密
- 非对称加密: 非对称加密使用一对密钥:公钥和私钥。公钥用于加密,私钥用于解密常见的非对称加密算法包括RSA(Rivest-Shamir-Adleman)、ECC(Elliptic Curve Cryptography)等。 非对称加密速度较慢,通常用于加密会话密钥等小数据量的信息,
HTTPS的安全特性
- 数据加密: HTTPS通过加密数据传输,防止数据在传输过程中被窃听或篡改。
- 数据完整性: HTTPS通过消息认证码(MAC,MessageAuthenticationCode)或哈希函数(如SHA-256)来确保数据的完整性,防止数据被篡改。
- 身份验证: HTTPS通过数字证书验证服务器的身份,确保客户端连接的是合法的服务器,防止中间人攻击。
HTTPS的加密机制主要包括以下几个步骤
- 建立连接: 客户端(例如浏览器)向服务器发送连接请求,并表明自己支持的加密协议和加密算法。
- 服务器响应: 服务器选择一个加密协议和加密算法,并发送给客户端,同时发送服务器的数字证书。数字证书包含服务器的公钥和由可信的证书颁发机构(CACertificate Authority)签名的服务器信息。
- 验证证书: 客户端验证服务器的数字证书,确认其合法性和真实性。这一步确保客户端连接的是正确的服务器,而不是中间人攻击者。
- 生成会话密钥: 客户端生成一个随机的会话密钥,并使用服务器的公钥对其进行加密。然后将加密后的会话密钥发送给服务器。服务器使用自己的私钥解密会话密钥
- 安全通信: 现在,客户端和服务器都拥有相同的会话密钥。接下来的通信使用对称加密算法(如AES)和这个会话密钥进行加密和解密
cookie和session有什么区别?
Cookie和Session都是Web开发中用于跟踪用户状态的技术,但它们在存储位置、数据容量、安全性以及生命周期等方面存在显著差异:
存储位置:Cookie的数据存储在客户端(通常是 浏览器)。当浏览器向服务器发送请求时,会自动附带Cookie中的数据。Session的数据存储在 服务器端。服务器为每个用户分配一个唯一的Session ID。这个ID通常 通过Cookie或URL重写 的方式发送给客户端,客户端后续的请求会带上这个Session ID,服务器根据ID查找对应的Session数据。
数据容量:单个Cookie的大小限制通常在4KB左右,而且大多数浏览器对每个域名的总Cookie数量也有限制。由于Session存储在服务器上,理论上不受数据大小的限制,主要受限于服务器的内存大小
安全性:Cookie相对不安全,因为数据存储在客户端,容易受到XSS(跨站脚本攻击)的威胁。不过,可以通过设置HttpOnly属性来防止JavaScript访问,减少XSS攻击的风险,但仍然可能受到CSRF(跨站请求伪造)的攻击。Session通常认为比Cookie更安全,因为敏感数据存储在服务器端。但仍然需要防范Session劫持(通过获取他人的SessionID)和会话固定攻击。
生命周期:Cookie可以设置过期时间,过期后自动删除。也可以设置为会话Cookie,即浏览器关闭时自动删除。Session在默认情况下,当用户关闭浏览器时,Session结束。但服务器也可以设置Sessior的超时时间,超过这个时间未活动,Session也会失效。
性能:使用Cookie时,因为数据随每个请求发送到服务器,可能会影响网络传输效率,尤其是在Cookie数据较大时。使用Session时,因为数据存储在服务器端,每次请求都需要查询服务器上的Session数据,这可能会增加服务器的负载,特别是在高并发场景下。
token,session,cookie的区别?
session存储于服务器,可以理解为一个状态列表,拥有一个唯一识别符号sessionld,通常存放于cookie中。服务器收到cookie后解析出sessionld,再去session列表中查找,才能找到相应session,因此依赖于cookie。
cookie类似一个令牌,装有sessionld,存储在客户端,浏览器通常会自动添加。
token也类似一个令牌,无状态,用户信息都被加密到token中,服务器收到token后解密就可知道是哪个用户,需要开发者手动添加。
如果客户端禁用了cookie,session还能用吗?
默认情况下禁用 cookie 后,!Session 是无法正常使用的,因为大多数 Web 服务器都是依赖于 Cookie 来传递 Session 的会话 ID 的。
客户端浏览器禁用 Cookie 时,服务器将 无法把会话 ID 发送给客户端,客户端也无法在后续请求中携带会话 ID 返回给服务器,从而导致服务器无法识别用户会话。
但是,有几种方法可以绕过这个问题,尽管它们可能会引入额外的复杂性和/或降低用户体验:
URL重写:每当服务器响应需要保持状态的请求时,将SessionID附加到URL中作为参数。例如,原本的链接
http://example.com/page变为http://example.com/page;jsessionid=XXXXXX
,服务器端需要相应地解析 URL 来获取 Session ID,并维护用户的会话状态。这种方式的缺点是URL变得不那么整洁且如果用户通过电子邮件或其他方式分享了这样的链接,可能导致SessionID的意外泄露。隐藏表单字段:在每个需要Session信息的HTML表单中包含一个隐藏字段,用来存储Session ID。当表。单提交时,Session ID随表单数据一起发送回服务器,服务器通过解析表单数据中的 Session ID 来获取用户的会话状态。这种方法仅适用于通过表单提交的交互模式,不适合链接点击或Ajax请求。
服务端正常启动了,但是客户端请求不到有哪些原因?如何排查?
如果客户端请求的接口没有响应,排查的方式:
- 检查接口IP地址是否正确,ping一下接口地址
- 检查被测接口端口号是否正确,可以在本机Telnet接口的IP和端口号,检查端口号能否连通
- 检查服务器的防火墙是否关闭,如果是以为安全或者权限问题不能关闭,需要找运维进行策略配置,开放对应的IP和端口。
- 检查你的客户端(浏览器、测试工具口),是否设置了网络代理,网络代理可以造成请求失败。
如果客户端的请求有响应,但是返回了错误状态码,那么根据错误码做对应的排查:
- 400:客户端请求错误,比如请求参数格式错误
- 401:未授权,比如请求header里,缺乏必要的信息头。(token,auth等)
- 403:禁止,常见原因是因为用户的账号没有对应的URL权限,还有就是项目中所用的中间件,不允许远程连接(Tomcat)
- 404:资源未找到,导致这种情况的原因很多,比如URL地址不正确
- 500:服务器内部错误,出现这种情况,说明服务器内部报错了,需要登录服务器,检查错误日志,根具体的提示信息在进行排查
- 502/503/504(错误的网关、服务器无法获得、网关超时):如果单次调用接口就报该错误,说明后端服务器配置有问题或者服务不可用,挂掉了:如果是并发压测时出现的,说明后端压力太大,出现异常,此问题一般是后端出现了响应时间过长或者是无响应造成的