1.3-网络知识点
Create by fall on 10 Oct 2023 Recently revised in 28 Mar 2024
简单
输入URL到页面渲染完成的过程
- URL解析:浏览器会先对输入的 URL 进行解析,包括检查URL的格式、协议、主机名等,确定要访问的站点地址。
- DNS解析:浏览器会向本地 DNS 服务器请求解析出该站点的 IP 地址。
- 建立连接:浏览器使用 TCP 协议与服务器建立连接,服务器回应确认建立连接。
- 发送请求:浏览器向服务器发送 HTTP 请求,请求的内容包括请求头和请求体。
- 服务器处理请求:服务器接收到请求后,会根据请求的内容进行处理,确定要返回的内容。
- 返回响应:服务器把处理好的内容通过 HTTP 响应报文返回给浏览器,响应的内容包括响应头和响应体。
- 浏览器渲染:浏览器拿到返回的响应后,对响应内容进行解析,构建DOM树、CSSOM树和 JavaScript 内存模型,然后把它们组合成渲染树,最后把渲染树展示给用户,页面呈现完成。
http 多个 tcp连接怎么实现的
某些服务器对 Connection: keep-alive 的 Header 进行了支持。意思是说,完成这个 HTTP 请求之后,不要断开 HTTP 请求使用的 TCP 连接。这样的好处是连接可以被重新使用,之后发送 HTTP 请求的时候不需要重新建立 TCP 连接,以及如果维持连接,那么 SSL 的开销也可以避免
keep-alive 是什么
什么是 KeepAlive
- KeepAlive可以简单理解为一种状态保持或重用机制,比如当一条连接建立后,我们不想它立刻被关闭,如果实现了 KeepAlive 机制,就可以通过它来实现连接的保持
- HTTP 的 KeepAlive 在HTTP 1.0版本默认是关闭的,但在 HTTP1.1 是默认开启的;操作系统里 TCP 的 KeepAlive 默认也是关闭,但一般应用都会修改设置来开启。因此网上TCP流量中基于 KeepAlive 的是主流
- HTTP 的 KeepAlive 和TCP的 KeepAlive 有一定的依赖关系,名称又一样,因此经常被混淆,但其实是不同的东西,下面具体分析一下
TCP 为什么要做 KeepAlive
- 我们都知道TCP的三次握手和四次挥手。当两端通过三次握手建立TCP连接后,就可以传输数据了,数据传输完毕,连接并不会自动关闭,而是一直保持。只有两端分别通过发送各自的FIN报文时,才会关闭自己侧的连接。
- 这个关闭机制看起来简单明了,但实际网络环境千变万化,衍生出了各种问题。假设因为实现缺陷、突然崩溃、恶意攻击或网络丢包等原因,一方一直没有发送FIN报文,则连接会一直保持并消耗着资源,为了防止这种情况,一般接收方都会主动中断一段时间没有数据传输的TCP连接,比如LVS会默认中断90秒内没有数据传输的TCP连接,F5会中断5分钟内没有数据传输的TCP连接
- 但有的时候我们的确不希望中断空闲的TCP连接,因为建立一次TCP连接需要经过一到两次的网络交互,且由于TCP的slow start机制,新的TCP连接开始数据传输速度是比较慢的,我们希望通过连接池模式,保持一部分空闲连接,当需要传输数据时,可以从连接池中直接拿一个空闲的TCP连接来全速使用,这样对性能有很大提升
- 为了支持这种情况,TCP实现了KeepAlive机制。KeepAlive机制并不是TCP规范的一部分,但无论Linux和Windows都实现实现了该机制。TCP实现里KeepAlive默认都是关闭的,且是每个连接单独设置的,而不是全局设置
- 另外有一个特殊情况就是,当某应用进程关闭后,如果还有该进程相关的TCP连接,一般来说操作系统会自动关闭这些连接
传输数据的格式
XML 进行数据传输
优点:标签种类丰富,传输量大
缺点:标签解析特别麻烦,不太适合轻量级数据
应用:大型门户网站:网易、新浪、凤凰网
json 数据传输格式
优点:数据轻量,解析比较轻松
缺点:传输的数据种类比较少,数据传输量比较小
应用:95%的移动端应用
OSI
OSI 模型,开放式系统互连通信模型(Open System Interconnection Reference Model)
一般都叫 OSI 参考模型,是 ISO(国际标准化组织)组织在1985年研究的网络互连模型。ISO为了更好的使网络应用更为普及,推出了OSI参考模型。其含义就是推荐所有公司使用这个规范来控制网络。这样所有公司都有相同的规范,就能互联了。 OSI定义了网络互连的七层框架(物理层、数据链路层、网络层、传输层、会话层、表示层、应用层),即ISO开放互连系统参考模型。
1.应用层
作用:它是与其他计算机进行通信的应用,它是对应应用程序的通信服务的。各种应用软件,包括web应用。
协议:DNS、FTP、HTTP、SMTP、TELNET、IRC、WHOIS
2.表示层
作用:这一层的主要作用是定义数据格式和加密。
3.会话层
作用:控制应用程序的会话能力,它定义了一段会话的开始、控制和结束,包括对多个双向消息的控制和管理,以便在只完成一部分消息时可以通知应用。
协议:
HTTP(Hyper text Transfer Protocol)协议:超文本传输协议使用TCP的80端口
FTP(File Transfer Protocol)文本传输协议
SMTP(Simple Mail Transfer Protocol)简单邮件传输协议,TCP是我25端口用户发邮件。
POP3(Post Office Protocol version3)邮局协议版本3,TCP的110号端口,用于收邮件的。
DNS(Domain Name System)域名解析协议。使用TCP和UDP的53号端口,作用是把www的域名解析成IP地址。
4.传输层
作用:对差错恢复协议和无差错恢复协议的选择,对同一主机上不同数据流的输入进行复用,对数据包进行重新排序。是最关键的一层,是唯一负责整体的数据传输和数据控制的。对上三层提供可靠的传输服务,对网络层提供可靠的目的地信息。在这一层数据的单位被称为数据段。
协议:TCP、UDP等
5.网络层
作用:主要负责寻找地址和路由选择,网络层还可以实现阻塞控制、网际互联等。
协议:IP、IPX、RIP、OSPF等
6.数据链路层
作用:负责物理层面上的互联的、节点间的通信传输;该层的作用包括:物理地址寻址、数据的成帧、流量控制、数据的检错、重发等。在这一层,数据的单位称为帧(frame)
协议:ARP、RARP、SDLC、HDLC、PPP、STP、帧中继等
7.物理层
作用:负责0、1 比特流(0/1序列)与电压的高低、逛的闪灭之间的转换 规定了激活、维持、关闭通信端点之间的机械特性、电气特性、功能特性以及过程特性;该层为上层协议提供了一个传输数据的物理媒体。在这一层,数据的单位称为比特(bit)。
典型规范:EIA/TIA RS-232、EIA/TIA RS-449、V.35、RJ-45、fddi令牌环网等
UDP 怎么用实现可靠传输,两条连接
最简单的方式是在应用层模仿传输层TCP的可靠性传输。下面不考虑拥塞处理,可靠UDP的简单设计。
- 添加seq/ack机制,确保数据发送到对端
- 添加发送和接收缓冲区,主要是用户超时重传。
- 添加超时重传机制。
详细说明:送端发送数据时,生成一个随机seq=x,然后每一片按照数据大小分配seq。数据到达接收端后接收端放入缓存,并发送一个ack=x的包,表示对方已经收到了数据。发送端收到了ack包后,删除缓冲区对应的数据。时间到后,定时任务检查是否需要重传数据。
目前有如下开源程序利用udp实现了可靠的数据传输。分别为*RUDP、RTP、UDT*。
1、RUDP(Reliable User Datagram Protocol)
*RUDP 提供一组数据服务质量增强机制,如拥塞控制的改进、重发机制及淡化服务器算法等*,从而在包丢失和网络拥塞的情况下, RTP 客户机(实时位置)面前呈现的就是一个高质量的 RTP 流。在不干扰协议的实时特性的同时,可靠 UDP 的拥塞控制机制允许 TCP 方式下的流控制行为。
2、RTP(Real Time Protocol)
*RTP为数据提供了具有实时特征的端对端传送服务*,如在组播或单播网络服务下的交互式视频音频或模拟数据。
应用程序通常在 UDP 上运行 RTP 以便使用其多路结点和校验服务;这两种协议都提供了传输层协议的功能。但是 RTP 可以与其它适合的底层网络或传输协议一起使用。如果底层网络提供组播方式,那么 RTP 可以使用该组播表传输数据到多个目的地。
RTP 本身并没有提供按时发送机制或其它服务质量(QoS)保证,它依赖于底层服务去实现这一过程。 RTP 并不保证传送或防止无序传送,也不确定底层网络的可靠性。 RTP 实行有序传送, RTP 中的序列号允许接收方重组发送方的包序列,同时序列号也能用于决定适当的包位置,例如:在视频解码中,就不需要顺序解码。
3、UDT(UDP-based Data Transfer Protocol)
基于UDP的数据传输协议(UDP-basedData Transfer Protocol,简称UDT)是一种互联网数据传输协议。*UDT的主要目的是支持高速广域网上的海量数据传输*,而互联网上的标准数据传输协议TCP在高带宽长距离网络上性能很差。
顾名思义,UDT建于UDP之上,并引入新的拥塞控制和数据可靠性控制机制。UDT是面向连接的双向的应用层协议。它同时支持可靠的数据流传输和部分可靠的数据报传输。由于UDT完全在UDP上实现,它也可以应用在除了高速数据传输之外的其它应用领域,例如点到点技术(P2P),防火墙穿透,多媒体数据传输等等。
数据量很大的时候 UDP 怎么可靠传输
参考答案:
基于UDP的数据传输协议(UDP-basedData Transfer Protocol,简称UDT)是一种互联网数据传输协议。*UDT的主要目的是支持高速广域网上的海量数据传输*,而互联网上的标准数据传输协议TCP在高带宽长距离网络上性能很差。
顾名思义,UDT建于UDP之上,并引入新的拥塞控制和数据可靠性控制机制。UDT是面向连接的双向的应用层协议。它同时支持可靠的数据流传输和部分可靠的数据报传输。由于UDT完全在UDP上实现,它也可以应用在除了高速数据传输之外的其它应用领域,例如点到点技术(P2P),防火墙穿透,多媒体数据传输等等。
504 如何排查
504(网关超时)服务器作为网关或代理,但是没有及时从上游服务器收到请求。
参考答案:
排查步骤:
- 检查500/502/504错误截图,判断是负载均衡问题,高防/安全网络配置问题,还是后端ECS配置问题。
- 如果有高防/安全网络,请确认高防/安全网络的七层转发配置正确。
- 请确认是所有客户端都有问题,还仅仅是部分客户端有问题。如果仅仅是部分客户端问题,排查该客户端是否被云盾阻挡,或者负载均衡域名或者IP是否被ISP运营商拦截。
- 检查负载均衡状态,是否有后端ECS健康检查失败的情况,如果有健康检查失败,解决健康检查失败问题。
- 在客户端用hosts文件将负载均衡的服务地址绑定到后端服务器的IP地址上,确认是否是后端问题。如果5XX错误间断发生,很可能是后端某一台ECS服务器的配置问题。
- 尝试将七层负载均衡切换为四层负载均衡,查看问题是否会复现。
- 检查后端ECS服务器是否存在CPU、内存、磁盘或网络等性能瓶颈。
- 如果确认是后端服务器问题,请检查后端ECS Web服务器日志是否有相关错误,Web服务是否正常运行,确认Web访问逻辑是否有问题,卸载服务器上杀毒软件重启测试。
- 检查后端ECS Linux操作系统的TCP内核参数是否配置正确。
tcp 是如何确保有效传输的,拥塞控制
通过以下7种方式确保有效传输
- 校验和
- 序列号
- 确认应答
- 超时重传
- 连接管理
- 流量控制
- 拥塞控制
TCP 拥塞控制
TCP不仅可以可以控制端到端的数据传输,还可以对网络上的传输进行监控。这使得TCP非常强大智能,它会根据网络情况来调整自己的收发速度。网络顺畅时就可以发的快,拥塞时就发的相对慢一些。拥塞控制算法主要有四种:慢启动,拥塞避免,快速重传,快速恢复。
- 慢启动和拥塞避免 慢启动和拥塞避免算法必须被TCP发送端用来控制正在向网络输送的数据量。为了 实现这些算法,必须向TCP每连接状态加入两个参量。拥塞窗口(cwnd)是对发送端收到确 认(ACK)之前能向网络传送的最大数据量的一个发送端限制,接收端通知窗口(rwnd)是对 未完成数据量的接收端限制。cwnd和rwnd的最小值决定了数据传送。 另一个状态参量,慢启动阀值(ssthresh),被用来确定是用慢启动还是用拥塞避免 算法来控制数据传送。 在不清楚环境的情况下向网络传送数据,要求TCP缓慢地探测网络以确定可用流量,避免突然传送大量数据而使网络拥塞。在开始慢启动时cwnd为1,每收到一个用于确认新数据的ACK至多增加SMSS(SENDER MAXIMUM SEGMENT SIZE)字节。 慢启动算法在cwndssthresh时使用。当cwnd和ssthresh相等时,发送端既可以使用慢启动也可以使用拥塞避免。 当拥塞发生时,ssthresh被设置为当前窗口大小的一半(cwnd和接收方通告窗口大小的最小值,但最少为2个报文段)。如果是超时重传,cwnd被设置为1个报文段(这就是慢启动,其实慢启动也不慢,它是指数性增长,只是它的起始比较低)当达到ssthresh时,进入拥塞避免算法(拥塞避免是线性增长)。
- 快速重传和快速恢复 当接收端收到一个顺序混乱的数据,它应该立刻回复一个重复的ACK。这个ACK的目的是通知发送端收到了一个顺序紊乱的数据段,以及期望的序列号。发送端收到这个重复的ACK可能有多种原因,可能丢失或者是网络对数据重新排序等。在收到三个重复ACK之后(包含第一次收到的一共四个同样的ACK),TCP不等重传定时器超时就重传看起来已经丢失(可能数据绕路并没有丢失)的数据段。因为这个在网络上并没有超时重传那么恶劣,所以不会进入慢启动,而进入快速恢复。快速恢复首先会把ssthresh减半(一般还会四舍五入到数据段的倍数),然后cwnd=ssthresh+收到重复ACK报文段累计的大小。
SSL 连接断开后如何恢复?
参考答案:
Session ID
每一次的会话都有一个编号,当对话中断后,下一次重新连接时,只要客户端给出这个编号,服务器如果有这个编号的记录,那么双方就可以继续使用以前的密钥,而不用重新生成一把。
Session Ticket
session ticket 是服务器在上一次对话中发送给客户的,这个 ticket 是加密的,只有服务器可能够解密,里面包含了本次会话的信息,比如对话密钥和加密方法等。这样不管我们的请求是否转移到其他的服务器上,当服务器将 ticket 解密以后,就能够获取上次对话的信息,就不用重新生成对话秘钥了。
hosts 文件是什么?
参考答案:
hosts 文件是个没有扩展名的系统文件,其作用就是将网址域名和其对应的 IP 地址建立一个关联“数据库”,当用户在浏览器中输入一个 url 时,系统会首先自动从 hosts 文件中寻找对应的 IP 地址。
同域请求的并发数限制的原因
参考答案:
浏览器的并发请求数目限制是针对同一域名的,同一时间针对同一域名下的请求有一定数量限制,超过限制数目的请求会被阻塞(chorme和firefox的限制请求数都是6个)。
限制其数量的原因是:基于浏览器端口的限制和线程切换开销的考虑,浏览器为了保护自己不可能无限量的并发请求,如果一次性将所有请求发送到服务器,也会造成服务器的负载上升。
cdn加速原理
参考答案:
- 当用户点击网站页面上的url时,经过本地dns系统解析,dns系统会将域名的解析权给交cname指向的cdn专用dns服务器。
- cdn的dns服务器将cdn的全局负载均衡设备ip地址返回给用户。
- 用户向cdn的全局负载均衡设备发起内容url访问请求。
- cdn全局负载均衡设备根据用户ip,以及用户请求的内容url,选择一台用户所属区域的区域负载均衡设备
- 区域负载均衡设备会为用户选择一台合适的缓存服务器提供服务,选择的依据包括:根据用户IP地址,判断哪一台服务器距用户最近;根据用户所请求的URL中携带的内容名称,判断哪一台服务器上有用户所需内容;查询各个服务器当前的负载情况,判断哪一台服务器尚有服务能力。基于以上这些条件的综合分析之后,区域负载均衡设备会向全局负载均衡设备返回一台缓存服务器的IP地址全局负载均衡设备把服务器的IP地址返回给用户。
- 用户向缓存服务器发起请求,缓存服务器响应用户请求,将用户所需内容传送到用户终端。如果这台缓存服务器上没有用户想要的内容,而区域均衡设备依然将它分配给了用户,那么这台服务器 就要向它的上一级缓存服务器发起请求内容,直至追溯到网站的源服务器将内容拉回给用户。
创建 ajax 过程
参考答案:
- 创建XMLHttpRequest对象,也就是创建一个异步调用对象.
- 创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
- 设置响应HTTP请求状态变化的函数.
- 发送HTTP请求.
- 获取异步调用返回的数据.
- 使用JavaScript和DOM实现局部刷新.
常用的http请求头以及响应头详
一、常用的http请求头
1.Accept
- Accept: text/html 浏览器可以接受服务器回发的类型为 text/html。
- Accept: */* 代表浏览器可以处理所有类型,(一般浏览器发给服务器都是发这个)。
2.Accept-Encoding
- Accept-Encoding: gzip, deflate 浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate),(注意:这不是只字符编码)。
3.Accept-Language
- Accept-Language:zh-CN,zh;q=0.9 浏览器申明自己接收的语言。
4.Connection
- Connection: keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。
- Connection: close 代表一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭, 当客户端再次发送Request,需要重新建立TCP连接。
5.Host(发送请求时,该报头域是必需的)
- Host: 请求报头域主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的。
6.Referer
- Referer: 当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理。
7.User-Agent
- User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36 告诉HTTP服务器, 客户端使用的操作系统和浏览器的名称和版本。
8.Cache-Control
- Cache-Control:private 默认为private 响应只能够作为私有的缓存,不能再用户间共享
- **
\**Cache-Control:public**
**响应会被缓存,并且在多用户间共享。正常情况, 如果要求HTTP认证,响应会自动设置为 private. - Cache-Control:must-revalidate 响应在特定条件下会被重用,以满足接下来的请求,但是它必须到服务器端去验证它是不是仍然是最新的。
- Cache-Control:no-cache 响应不会被缓存,而是实时向服务器端请求资源。
- Cache-Control:max-age=10 设置缓存最大的有效时间,但是这个参数定义的是时间大小(比如:60)而不是确定的时间点。单位是[秒 seconds]。
- Cache-Control:no-store在任何条件下,响应都不会被缓存,并且不会被写入到客户端的磁盘里,这也是基于安全考虑的某些敏感的响应才会使用这个。
9.Cookie
Cookie是用来存储一些用户信息以便让服务器辨别用户身份的(大多数需要登录的网站上面会比较常见),比如cookie会存储一些用户的用户名和密码,当用户登录后就会在客户端产生一个cookie来存储相关信息,这样浏览器通过读取cookie的信息去服务器上验证并通过后会判定你是合法用户,从而允许查看相应网页。当然cookie里面的数据不仅仅是上述范围,还有很多信息可以存储是cookie里面,比如sessionid等。
10.Range(用于断点续传)
- Range:bytes=0-5 指定第一个字节的位置和最后一个字节的位置。用于告诉服务器自己想取对象的哪部分。
常用的http响应头
1.Cache-Control(对应请求中的Cache-Control)
- Cache-Control:private 默认为private 响应只能够作为私有的缓存,不能再用户间共享
- *Cache-Control:public* 浏览器和缓存服务器都可以缓存页面信息。
- Cache-Control:must-revalidate 对于客户机的每次请求,代理服务器必须想服务器验证缓存是否过时。
- Cache-Control:no-cache 浏览器和缓存服务器都不应该缓存页面信息。
- Cache-Control:max-age=10 是通知浏览器10秒之内不要烦我,自己从缓冲区中刷新。
- Cache-Control:no-store 请求和响应的信息都不应该被存储在对方的磁盘系统中。
2.Content-Type
- Content-Type:text/html;charset=UTF-8 告诉客户端,资源文件的类型,还有字符编码,客户端通过utf-8对资源进行解码,然后对资源进行html解析。通常我们会看到有些网站是乱码的,往往就是服务器端没有返回正确的编码。
3.Content-Encoding
- Content-Encoding:gzip 告诉客户端,服务端发送的资源是采用gzip编码的,客户端看到这个信息后,应该采用gzip对资源进行解码。
4.Date
- Date: Tue, 03 Apr 2018 03:52:28 GMT 这个是服务端发送资源时的服务器时间,GMT是格林尼治所在地的标准时间。http协议中发送的时间都是GMT的,这主要是解决在互联网上,不同时区在相互请求资源的时候,时间混乱问题。
5.Server
- Server:Tengine/1.4.6 这个是服务器和相对应的版本,只是告诉客户端服务器信息**。**
6.Transfer-Encoding
- Transfer-Encoding:chunked 这个响应头告诉客户端,服务器发送的资源的方式是分块发送的。一般分块发送的资源都是服务器动态生成的,在发送时还不知道发送资源的大小,所以采用分块发送,每一块都是独立的,独立的块都能标示自己的长度,最后一块是0长度的,当客户端读到这个0长度的块时,就可以确定资源已经传输完了。
7.Expires
- Expires:Sun, 1 Jan 2000 01:00:00 GMT 这个响应头也是跟缓存有关的,告诉客户端在这个时间前,可以直接访问缓存副本,很显然这个值会存在问题,因为客户端和服务器的时间不一定会都是相同的,如果时间不同就会导致问题。所以这个响应头是没有Cache-Control:max-age=*这个响应头准确的,因为max-age=date中的date是个相对时间,不仅更好理解,也更准确。
8.Last-Modified
- Last-Modified: Dec, 26 Dec 2015 17:30:00 GMT 所请求的对象的最后修改日期(按照 RFC 7231 中定义的“超文本传输协议日期”格式来表示)
9.Connection
- Connection:keep-alive 这个字段作为回应客户端的Connection:keep-alive,告诉客户端服务器的tcp连接也是一个长连接,客户端可以继续使用这个tcp连接发送http请求。
10.Etag
- ETag: "737060cd8c284d8af7ad3082f209582d" 就是一个对象(比如URL)的标志值,就一个对象而言,比如一个html文件,如果被修改了,其Etag也会别修改,所以,ETag的作用跟Last-Modified的作用差不多,主要供WEB服务器判断一个对象是否改变了。比如前一次请求某个html文件时,获得了其 ETag,当这次又请求这个文件时,浏览器就会把先前获得ETag值发送给WEB服务器,然后WEB服务器会把这个ETag跟该文件的当前ETag进行对比,然后就知道这个文件有没有改变了。
11.Refresh
- **Refresh: ** 用于重定向,或者当一个新的资源被创建时。默认会在5秒后刷新重定向。
12.Access-Control-Allow-Origin
- Access-Control-Allow-Origin: * 号代表所有网站可以跨域资源共享,如果当前字段为那么Access-Control-Allow-Credentials就不能为true
- Access-Control-Allow-Origin: www.baidu.com 指定哪些网站可以跨域资源共享
13.Access-Control-Allow-Methods
- Access-Control-Allow-Methods:GET,POST,PUT,DELETE 允许哪些方法来访问
14.Access-Control-Allow-Credentials
- Access-Control-Allow-Credentials: true 是否允许发送cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。如果access-control-allow-origin为*,当前字段就不能为true
15.Content-Range
- Content-Range: bytes 0-5/7877 指定整个实体中的一部分的插入位置,他也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。
http 缓存策略
http 缓存策略
浏览器每次发起请求时,先在本地缓存中查找结果以及缓存标识,根据缓存标识来判断是否使用本地缓存。如果缓存有效,则使用本地缓存;否则,则向服务器发起请求并携带缓存标识。根据是否需向服务器发起HTTP请求,将缓存过程划分为两个部分: 强制缓存和协商缓存,强缓优先于协商缓存。
- 强缓存,服务器通知浏览器一个缓存时间,在缓存时间内,下次请求,直接用缓存,不在时间内,执行比较缓存策略。
- 协商缓存,让客户端与服务器之间能实现缓存文件是否更新的验证、提升缓存的复用率,将缓存信息中的Etag和Last-Modified 通过请求发送给服务器,由服务器校验,返回304状态码时,浏览器直接使用缓存。
HTTP缓存都是从第二次请求开始的:
-
第一次请求资源时,服务器返回资源,并在response header中回传资源的缓存策略;
-
第二次请求时,浏览器判断这些请求参数,击中强缓存就直接200,否则就把请求参数加到request header头中传给服务器,看是否击中协商缓存,击中则返回304,否则服务器会返回新的资源。这是缓存运作的一个整体流程图:
-
强缓存
-
强缓存命中则直接读取浏览器本地的资源,在network中显示的是from memory或者from disk
-
控制强制缓存的字段有:Cache-Control(http1.1)和Expires(http1.0)
-
Cache-control是一个相对时间,用以表达自上次请求正确的资源之后的多少秒的时间段内缓存有效。
-
Expires是一个绝对时间。用以表达在这个时间点之前发起请求可以直接从浏览器中读取数据,而无需发起请求
-
Cache-Control的优先级比Expires的优先级高。前者的出现是为了解决Expires在浏览器时间被手动更改导致缓存判断错误的问题。 如果同时存在则使用Cache-control。
-
强缓存-expires
-
该字段是服务器响应消息头字段,告诉浏览器在过期时间之前可以直接从浏览器缓存中存取数据。
-
Expires 是 HTTP 1.0 的字段,表示缓存到期时间,是一个绝对的时间 (当前时间+缓存时间)。在响应消息头中,设置这个字段之后,就可以告诉浏览器,在未过期之前不需要再次请求。
-
由于是绝对时间,用户可能会将客户端本地的时间进行修改,而导致浏览器判断缓存失效,重新请求该资源。此外,即使不考虑修改,时差或者误差等因素也可能造成客户端与服务端的时间不一致,致使缓存失效。
-
优势特点
- HTTP 1.0 产物,可以在HTTP 1.0和1.1中使用,简单易用。
- 以时刻标识失效时间。
-
劣势问题
- 时间是由服务器发送的(UTC),如果服务器时间和客户端时间存在不一致,可能会出现问题。
- 存在版本问题,到期之前的修改客户端是不可知的。
-
强缓存-cache-control
-
已知Expires的缺点之后,在HTTP/1.1中,增加了一个字段Cache-control,该字段表示资源缓存的最大有效时间,在该时间内,客户端不需要向服务器发送请求。
-
这两者的区别就是前者是绝对时间,而后者是相对时间。下面列举一些Cache-control字段常用的值:(完整的列表可以查看MDN)
- max-age:即最大有效时间。
- must-revalidate:如果超过了max-age的时间,浏览器必须向服务器发送请求,验证资源是否还有效。
- no-cache:不使用强缓存,需要与服务器验证缓存是否新鲜。
- no-store: 真正意义上的“不要缓存”。所有内容都不走缓存,包括强制和对比。
- public:所有的内容都可以被缓存 (包括客户端和代理服务器, 如 CDN)
- private:所有的内容只有客户端才可以缓存,代理服务器不能缓存。默认值。
-
Cache-control 的优先级高于 Expires,为了兼容 HTTP/1.0 和 HTTP/1.1,实际项目中两个字段都可以设置。
-
该字段可以在请求头或者响应头设置,可组合使用多种指令:
- 可缓存性
- public:浏览器和缓存服务器都可以缓存页面信息
- private:default,代理服务器不可缓存,只能被单个用户缓存
- no-cache:浏览器器和服务器都不应该缓存页面信息,但仍可缓存,只是在缓存前需要向服务器确认资源是否被更改。可配合private, 过期时间设置为过去时间。
- only-if-cache:客户端只接受已缓存的响应
- 到期
- max-age=:缓存存储的最大周期,超过这个周期被认为过期。
- s-maxage=:设置共享缓存,比如can。会覆盖max-age和expires。
- max-stale[=]:客户端愿意接收一个已经过期的资源
- min-fresh=:客户端希望在指定的时间内获取最新的响应
- stale-while-revalidate=:客户端愿意接收陈旧的响应,并且在后台一部检查新的响应。时间代表客户端愿意接收陈旧响应 的时间长度。
- stale-if-error=:如新的检测失败,客户端则愿意接收陈旧的响应,时间代表等待时间。
- 重新验证和重新加载
- must-revalidate:如页面过期,则去服务器进行获取。
- proxy-revalidate:用于共享缓存。
- immutable:响应正文不随时间改变。
- 其他
- no-store:绝对禁止缓存
- no-transform:不得对资源进行转换和转变。例如,不得对图像格式进行转换。
- 可缓存性
-
优势特点
- HTTP 1.1 产物,以时间间隔标识失效时间,解决了Expires服务器和客户端相对时间的问题。
- 比Expires多了很多选项设置。
-
劣势问题
- 存在版本问题,到期之前的修改客户端是不可知的。
-
协商缓存
- 协商缓存的状态码由服务器决策返回200或者304
- 当浏览器的强缓存失效的时候或者请求头中设置了不走强缓存,并且在请求头中设置了If-Modified-Since 或者 If-None-Match 的时候,会将这两个属性值到服务端去验证是否命中协商缓存,如果命中了协商缓存,会返回 304 状态,加载浏览器缓存,并且响应头会设置 Last-Modified 或者 ETag 属性。
- 对比缓存在请求数上和没有缓存是一致的,但如果是 304 的话,返回的仅仅是一个状态码而已,并没有实际的文件内容,因此 在响应体体积上的节省是它的优化点。
- 协商缓存有 2 组字段(不是两个),控制协商缓存的字段有:Last-Modified/If-Modified-since(http1.0)和Etag/If-None-match(http1.1)
- Last-Modified/If-Modified-since表示的是服务器的资源最后一次修改的时间;Etag/If-None-match表示的是服务器资源的唯一标 识,只要资源变化,Etag就会重新生成。
- Etag/If-None-match的优先级比Last-Modified/If-Modified-since高。
-
协商缓存-协商缓存-Last-Modified/If-Modified-since
-
服务器通过Last-Modified字段告知客户端,资源最后一次被修改的时间,例如Last-Modified: Mon, 10 Nov 2018 09:10:11 GMT
-
浏览器将这个值和内容一起记录在缓存数据库中。
-
下一次请求相同资源时时,浏览器从自己的缓存中找出“不确定是否过期的”缓存。因此在请求头中将上次的Last-Modified的值写入到请求头的If-Modified-Since字段
-
服务器会将If-Modified-Since的值与Last-Modified字段进行对比。如果相等,则表示未修改,响应 304;反之,则表示修改了,响应 200 状态码,并返回数据。
-
优势特点
- 不存在版本问题,每次请求都会去服务器进行校验。服务器对比最后修改时间如果相同则返回304,不同返回200以及资源内容。
-
劣势问题
- 只要资源修改,无论内容是否发生实质性的变化,都会将该资源返回客户端。例如周期性重写,这种情况下该资源包含的数据实际上一样的。
- 以时刻作为标识,无法识别一秒内进行多次修改的情况。 如果资源更新的速度是秒以下单位,那么该缓存是不能被使用的,因为它的时间单位最低是秒。
- 某些服务器不能精确的得到文件的最后修改时间。
- 如果文件是通过服务器动态生成的,那么该方法的更新时间永远是生成的时间,尽管文件可能没有变化,所以起不到缓存的作用。
-
协商缓存-Etag/If-None-match
- 为了解决上述问题,出现了一组新的字段Etag和If-None-Match
- Etag存储的是文件的特殊标识(一般都是 hash 生成的),服务器存储着文件的Etag字段。之后的流程和Last-Modified一致,只是Last-Modified字段和它所表示的更新时间改变成了Etag字段和它所表示的文件 hash,把If-Modified-Since变成了If-None-Match。服务器同样进行比较,命中返回 304, 不命中返回新资源和 200。
- 浏览器在发起请求时,服务器返回在Response header中返回请求资源的唯一标识。在下一次请求时,会将上一次返回的Etag值赋值给If-No-Matched并添加在Request Header中。服务器将浏览器传来的if-no-matched跟自己的本地的资源的ETag做对比,如果匹配,则返回304通知浏览器读取本地缓存,否则返回200和更新后的资源。
- Etag 的优先级高于 Last-Modified。
- 优势特点
- 可以更加精确的判断资源是否被修改,可以识别一秒内多次修改的情况。
- 不存在版本问题,每次请求都回去服务器进行校验。
- 劣势问题
- 计算ETag值需要性能损耗。
- 分布式服务器存储的情况下,计算ETag的算法如果不一样,会导致浏览器从一台服务器上获得页面内容后到另外一台服务器上进行验证时现ETag不匹配的情况。
no-store 和 no-cache 的区别
no-cache 和 no-store 都是 HTTP 协议头 Cache-Control 的值。
区别是:
-
no-store
彻底禁用缓冲,所有内容都不会被缓存到缓存或临时文件中。
-
no-cache
在浏览器使用缓存前,会往返对比 ETag,如果 ETag 没变,返回 304,则使用缓存。
Cache-Control和expires区别是什么,哪个优先级高
Cache-Control 和 expires 区别:
Cache-Control 设置时间长度
Expires 设置时间点
优先级:
强缓存 expires 和 cache-control 同时存在时,则 cache-control 会覆盖 expires,expires 无论有没有过期,都无效。 即:cache-control 优先级 > expires 优先级。
什么是粘包问题,如何解决?
默认情况下,TCP 连接会采用延迟传送算法(Nagle 算法),在数据发送之前缓存他们。如果短时间有多个数据发送,会缓冲到一起作一次发送(缓冲大小是 socket.bufferSize),这样可以减少 IO 消耗提高性能。(TCP 会出现这个问题,HTTP 协议解决了这个问题)
解决方法
- 多次发送之前间隔一个等待时间:处理简单,但是影响传输效率
- 关闭 Nagle 算法:消耗资源高,整体性能下降
- 封包/拆包:使用一些有标识来进行封包拆包(类似 HTTP 协议头尾)
参考:
文章名称 | 链接 |
---|---|
牛客网 | 前端工程师面试宝典 |