前端需要知道的浏览器机制

HTTP与HTTPS的概念

HTTP:超文本传输协议,是应用层的一个协议,定义了超文本的传输的标准。

HTTPS:是HTTP的一种,以安全为重点的HTTP,在HTTP的基础上加入了SSL,因此可以看作HTTPS = HTTP + SSL。HTTPS的安全基础是SSL,通过SSL进行传输加密与身份认证,保证了传输过程的安全性。

  • 超文本:我理解的是超级文本,包含了许多超出普通文本范畴的东西,比如图片、视频等等。
  • 网络协议主要由语法、语义、同步三要素组成。语法即数据与控制信息的结构或格式;语义即需要发出何种控制信息,完成何种动作以及做出何种响应;同步即事件实现顺序的详细说明。
  • 应用层:网络模型中的一层,因特网的协议栈由五个部分组成:物理层、链路层、网络层、运输层和应用层。应用层是网络应用程序和网络协议存放的分层。
  • SSL:安全套接层,一种网络安全协议,在TCP/IP上实现的安全协议。

通俗点说,HTTP就是说话的语言、语法,规定了我们要怎么说话,以及说话时语句怎么组成。而HTTPS则相当于暗语,只有说话者和目标者知道并能听懂。

计算机网络体系结构

为了让两个相互通信的计算机系统能够高度协调工作,设计者使用了‘分层’的方法将这一复杂困难的问题转化为了若干小问题。计算机网络体系结构就这样诞生了。计算机网络体系结构有OSI体系结构、TCP/IP体系结构、还有为了便于教学计算机网络原理而产生的五层协议的体系结构。

OSI/RM标准

OSI/RM标准,中文名称是开放系统互连基本参考模型。是由ISO国际标准化组织提出的国际标准。但是由于制定该标准时,制定的专家、学者多为原先电信网络的专家、学者,仍秉持着电信网络的理念来设计标准,并且缺乏互联网的实际经验,导致OSI标准缺乏商业驱动力,并且实行起来过于复杂,运行效率低下。并且因为在设计时过多的追求完善,导致OSI标准制定之后,市场已被使用TCP/IP协议的互联网抢占,无法及时进入市场,导致OSI/RM标准仅仅只是ISO认可的法律上的国际标准,而非事实上的国际标准。

TCP/IP标准

与OSI/RM标准邀请一大堆专家学者参与制定标准相反,TCP/IP协议是由企业提出,并在发展中一步步完善的,与OSI/RM标准相比,TCP/IP标准更加简洁,商业气息更加浓厚,更为适合互联网的环境,并且因为TCP/IP的早早提出,使得TCP/IP协议成为了实际上的国际标准。

五层协议的体系结构

需要注意的是,虽然TCP/IP协议名义上有四层结构,但是最下层的链路层并没有属于TCP/IP体系的具体协议,因此,TCP/IP实质上只有最上面的三层。为了方便阐述计算机网络原理(并非新发展的一种体系结构),综合OSI和TCP/IP的优点,提出了五层协议的体系结构(实际使用仍使用TCP/IP协议)。

以上三种类型的计算机网络体系结构图如下

TCP/IP

TCP/IP协议,并不仅仅指的是TCP协议和IP协议两个协议,而是以这两个协议为中心,围绕着这两个协议的许多协议组成的协议簇。

TCP协议,即传输控制协议,与用户数据报协议UDP同为传输层的协议。TCP协议与UDP协议的区别在于TCP协议是一个面向连接的、可靠的、基于字节流的协议,而UDP则是面向无连接的协议。面向连接指的是客户端与服务器之间的连接,在TCP协议下,客户端与服务器简历连接之前需要进行三次握手,确保客户端与服务器都拥有发送与接收的能力。不仅如此,TCP还会记录数据发送的情况,避免因为丢包或网络问题导致数据接收不到。因此TCP是有状态的、可控的,而UDP是无状态的、不可控的。面向字节流是TCP为了维护状态,在数据传输中将IP包变成了字节流,而UDP则是基于数据的。由于TCP有状态且可控,相较于UDP更为安全,因此HTTP协议使用TCP协议做为通讯协议。

IP协议的英文全称为Internet Protocol,即网际互联协议,他解决了通信双方寻址的问题,相当于给每一台计算机配备了一个编号,通过这个编号来辨别不同的计算机。

TCP三次握手

  • 第一次握手:建立连接时,客户端发送syn包(syn=j) 到服务器,并进入SYN_ SENT状态,等待服务器确认。
  • 第二次握手:服务器收到syn包并确认客户的syn(ack=j+1),同时也发送一个自己的syn包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
  • 第三次握手:客户端收到服务器的syn+ack包,向服务器发送确认包ack(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

SYN:同步序列编号。

TCP四次挥手

初始双方处于ESTABLISHED状态,此时用户端向服务端发送FIN报文,序列号为seq=u,用户端进入FIN-WAIT-1状态。服务器端接收到之后,进入CLOSED-WAIT状态。并向用户端发送ACK报文,ack=u+1。用户端接收到报文后,进入FIN-WAIT-2状态.随后服务器端向用户端发送FIN、ACK报文,seq=n,ack=u+1.之后服务器端进入LAST-ACK状态。用户端接收到之后,向服务器端发送ACK报文,ack=n+1,之后进入TIME-WAIT状态等待2MSL,确定不会再接收到来自服务器端的信息,进入CLOSED状态。服务器端接收到ACK报文后,进入CLOSED状态。

为什么会有TIME-WAIT状态:确定没有后续的来自服务器端的包,避免数据包混乱。

等待2MSL:1 个 MSL 确保四次挥手中主动关闭方最后的 ACK 报文最终能达到对端;1 个 MSL 确保对端没有收到 ACK 重传的 FIN 报文可以到达。

URI/URL

URI是统一资源标识符,URL是统一资源定位符,我们常常说的网址就是URL。URI由URL与URN(统一资源名称)组成。

由于URI在网上任意位置都能访问到.因此,HTTP协议使用URI定位网上的资源.

浏览器架构

多进程的浏览器

首先,我们需要知道浏览器是多进程的,每当我们点开一个页面,浏览器都会使用系统分配的cpu、内存等资源,开启一个新的进程,因此,我们可以得知,每一个页面,都是一个独立的浏览器进程,这一进程就是浏览器渲染进程,也叫做Renderer进程,是浏览器的内核,具有页面渲染,脚本执行,事件处理等功能,对于我们前端来说,是浏览器最重要的进程。

除了渲染进程,浏览器还有哪些进程?

(1)主进程,也叫做Browser进程,作用如下

  • 协调控制、创建销毁其他的子进程。
  • 负责浏览器界面显示,用户交互,后退,前进,收藏等。
  • 将渲染进程得到的内存中的Bitmap,绘制到用户界面中。
  • 处理网络请求、网络资源的管理与下载。

(2)第三方插件进程:每种类型的插件都对应一个进程,仅当使用某个插件的时候才创建。

(3)GPU进程:用于进行3D绘制

浏览器为什么要设计成多进程的?

为了避免因为某一个页面的崩溃或者某一个插件的问题而导致卡死,致使其他页面也受到影响。

多线程的渲染进程

(1)GUI 渲染线程

  • 负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。
  • 页面需要重绘和回流时,该线程就会执行
  • 与js引擎线程互斥,防止渲染结果不可预期

(2)JS 引擎线程

  • 负责解析处理Javascript脚本程序。
  • 单线程
  • 与GUI引擎线程互斥,防止渲染结果不可预期

(3)定时器触发线程

setInterval与setTimeout所在的线程,由于JS引擎线程是单线程,但是又不能因为定时器而妨碍后续代码解析(这样会导致js运行时间过长,不仅仅无法达到预期中使用定时器的效果,还会因为js引擎线程与GUI线程的互斥,导致页面渲染加载堵塞),因此单独使用这个线程进行定时器的计时。

(4)浏览器事件线程

  • 归属于浏览器而不是JS引擎,用来控制事件循环,当JS引擎执行如鼠标点击、setTimeout、ajax等代码块时,会将对应代码添加至浏览器事件线程中。
  • 当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理
  • 例:当事件为setInterval与setTimeout时,是由定时器触发线程计时,当时间符合时,添加到待处理队列对尾。

(5)http 异步线程

  • 浏览器有一个单独的线程用于处理AJAX请求。
  • 当请求完成时,若有回调函数,通知事件触发线程。

GUI线程为何与JS引擎线程互斥

为了避免当GUI线程渲染完某一部分时,js引擎线程将已渲染那部分的某个数据进行修改,导致需要重新渲染或者出现不可预期的错误,因此浏览器设置两个线程互斥。

Event Loop事件循环

同步任务和异步任务

JS 任务分为同步任务和异步任务两种,同步任务都在JS引擎线程上执行,形成一个执行栈。异步任务往往占用资源多且耗时久,会进入事件列表并注册函数,当满足异步任务的条件时,将回调事件放入任务队列中。当执行栈中所有的同步任务执行完毕后,此时JS引擎线程空闲,系统会读取任务队列,将可运行的异步任务回调事件添加到执行栈中,开始执行。

宏任务和微任务

微任务和宏任务皆为异步任务,它们都属于一个队列,主要区别在于他们的执行顺序,Event Loop的走向和取值。

宏任务:主代码块,setTimeout,setInterval等。

微任务:Promise,process.nextTick等。

宏任务与微任务的执行

首先会从任务队列中获取一个宏任务执行,执行过程中产生的微任务放入微任务的任务队列中,每当一个宏任务执行完毕后,事件循环都会先查询任务队列中是否有微任务存在,如果有,将所有微任务执行完毕之后,开始检查渲染,由GUI线程接管(避免因js任务队列过多而导致页面渲染加载堵塞,产生不可预期的后果),如果没有,直接开始检查渲染,由GUI线程接管。当渲染完毕之后,执行下一个宏任务。

从输入网址到页面展现发生了什么

我们以下面这条网址为例

https://search.bilibili.com/all?keyword=HTTP&from_source=webtop_search

  1. 首先判断网址是否为合法的URL连接,合法且完整的URL链接,由protocol协议、hostname主机名、port端口号、pathname、search几部分组成。上面的网址,https是protocol协议,search.bilibili.com是hostname主机名,port端口号未显示,/all是pathname,search部分是  ?keyword=HTTP&from_source=webtop_search。倘若URL链接不合法,就将输入内容做为搜索条件,使用默认的搜索引擎进行搜索。如果合法,判断是否完整,不完整的话一定程度上对域进行猜测补全,之后进入下一步,完整的话直接进入下一步。当url解析到http协议部分时,浏览器主线程接管,之后就会新建一个网络线程去请求资源。
  2. 在判断完URL之后,就进行DNS解析通过域名,也就是上述网址中的search.bilibili.com,首先检查浏览器的缓存和本地的hosts文件,如果有记录则直接使用对应的IP地址,否则在本地的DNS解析器缓存中查找,如果没有,则使用TCP/IP 参数中设置的 DNS 服务器进行查询。如果要查询的域名包含在本地配置区域资源中,则返回解析结果,完成域名解析,倘若也不在本地配置区域资源中,检查本地 DNS 服务器是否缓存该网址记录,有则返回解析结果,没有的话则本地 DNS 服务器发送查询报文至根 DNS 服务器,根 DNS 服务器收到请求后,用顶级域 DNS 服务器地址进行响应。之后本地 DNS 服务器发送查询报文至顶级域 DNS 服务器。顶级域 DNS 服务器收到请求后,用权威 DNS 服务器地址进行响应。最后本地 DNS 服务器发送查询报文至权威 DNS 服务器,权威 DNS 服务器收到请求后,用 search.bilibili.com 的 IP 地址进行响应,完成域名解析。
  3. 当浏览器获取到服务器的 IP 地址后,浏览器会用一个随机的端口向服务器端口发起 TCP 连接请求,如果是HTTP,则是80端口,如果是HTTPS,是443端口。这个连接请求到达服务端后,通过 TCP 三次握手,建立 TCP 的连接。

  4. TCP链接建立后,倘若使用的是HTTP协议,就可以直接进行数据传输了,但是倘若使用的是HTTPS,则还需要多进行TLS协商这一步操作,来在两个通信应用程序之间提供保密性和数据完整性。

  5. 浏览器到web服务器的连接建立后,浏览器会发送一个初始的 HTTP GET 请求,请求目标通常是一个 HTML 文件。服务器收到请求后,将发回一个 HTTP 响应报文,内容包括相关响应头和 HTML 正文。

  6. TCP四次挥手断开连接。

  7. 浏览器根据获取到的数据,进行解析和绘制,大致流程如下:

    构建DOM树:解析HTML语法,然后解析成DOM树,树由dom元素及属性节点组成,树的根是document对象。

    构建CSS规则树:生成CSS规则树

    构建render树:Web浏览器将DOM和CSSOM结合,并构建出渲染树(render tree)

    布局:计算出每个节点在屏幕中的位置

    绘制:即遍历render树,并使用UI后端层绘制每个节点。

    浏览器将各层信息发送给GPU进程,GPU将各层合成,在屏幕上显示。

  8. js引擎解析js文件,执行js代码。

DNS解析

DNS解析的作用是将网址自动转换成IP地址来进行通信,例如在对www.baidu.com进行DNS解析时,会将其解析为www(三级域名),baidu(二级域名),com(顶级域名)这三个域名。上述案例中的search.bilibili.com,解析完成之后,就变成了search(查询,三级域名),bilibili(哔哩哔哩,二级域名),com(工商企业,顶级域名)。该案例之所以没有www,是因为哔哩哔哩在申请域名的时候提交了不带www的解析方案,因此可以不加www。具体的DNS解析过程,如前文所述。

重绘与重排

重绘(repaint或redraw):重绘是指一个元素外观的改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。

重排(重构/回流/reflow):当渲染树中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建, 这就称为回流(reflow)。每个页面至少需要一次回流,就是在页面第一次加载的时候。

重绘和重排的关系:在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程称为重绘。

重排必定会引发重绘,但重绘不一定会引发重排。

触发重排的条件

  • 页面渲染初始化;(无法避免)
  • 添加或删除可见的DOM元素;
  • 元素位置的改变;
  • 元素尺寸的改变;
  • 浏览器窗口尺寸的变化;
  • 填充内容的改变;
  • 读取某些元素属性;

优化方案:

  • 减少逐项更改样式,最好将样式定义为class一次性更新;
  • 避免循环操作dom,创建一个div,在它上面应用所有DOM操作,最后再把它添加到window.document;
  • 避免多次读取offset等属性。无法避免则将它们缓存到变量;
  • 将复杂的元素绝对定位或固定定位,使得它脱离文档流,否则回流代价会很高;
  • 使用 transform 替代 top;
  • 使用 visibility 替换 display: none ,因为前者只会引起重绘,后者会引发回流(改变了布局);
  • 不要把节点的属性值放在一个循环里当成循环里的变量;
  • 不要使用table布局,因为一个小小的改动可能会导致table重新布局;
  • 动画实现的速度的选择,动画速度越快,回流次数越多;
  • 将频繁重绘或者回流的节点设置为图层,图层能够阻止该节点的渲染行为影响别的节点。比如对于 video 标签来说,浏览器会自动将该节点变为图层。

HTTP请求报文

http请求报文由请求行,消息头部、空行、请求正文四个部分组成。

  1. 请求行:请求行由请求方法、URL、HTTP协议版本三个字段组成。之间用空格分隔。请求可在浏览器控制台部分查看,我用的是火狐浏览器,可以在控制台网络部分查看请求的详细信息,查看请求报文,请求行如下

    GET /api/ tooltip/ query.list.do HTTP/2

    其中GET是请求方法,/api/ tooltip/ query.list.do是URL,HTTP/2是HTTP协议版本。

  2. 消息头部:具体内容大致如下

    Host:请求的主机名

    User-Agent: 发出请求的浏览器类型

    Accept: 客户端可识别的内容类型

    Accept-Language:  浏览器想要获取的数据的语言类型

    Accept- Encoding:浏览器支持的编码类型

    Connection:浏览器告诉服务器是持久连接还是非持久连接

  3. 空行:最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头。
  4. 请求数据:请求数据常常在POST方法中使用,用于在请求的时候带上接口所需的数据。

常用的HTTP请求方法有如下几种

  • GET: 用于获取资源的请求方法,用来请求访问已被 URI 识别的资源。指定的资源经服务器端解析后返回响应内容。
  • POST:向浏览器发送数据,传输实体主体。
  • PUT:  传输文件
  • DELETE: 删除文件

HTTP响应报文

http响应报文由状态行、响应头、空行和响应体四个部分组成。响应报文大致如下。

HTTP/2 200 OK
date: Thu, 01 Sep 2022 02:23:36 GMT
content-type: text/html; charset=utf-8
gear: 1
data: wss://*.bilibili.com:* *.bilibili.com *.hdslb.com *.biliapi.net *.biliapi.com; frame-ancestors 'self' *.bilibili.com *.biligame.com; report-uri https://security.bilibili.com/csp_report
expires: Thu, 01 Sep 2022 02:23:35 GMT
cache-control: no-cache
x-cache-webcdn: BYPASS from blzone01
content-encoding: br
X-Firefox-Spdy: h2

  1. 状态行:状态行由三部分组成:服务器HTTP协议版本,响应状态码,状态码的文本描述。上面的响应报文中,状态行为 HTTP/2 200 OK  ,其中HTTP/2 为服务器HTTP协议版本,200是响应状态码,OK是状态码的文本描述。

    状态码开头为1,即状态码为1XX,表示请求已接收,继续处理。

    100 Continue 继续。客户端应继续其请求。

    101 Switching Protocols: 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议。


    状态码开头为2,表示请求已被成功接受,处理。

    200 OK:客户端请求成功。

    201 Created:已创建,成功请求并创建了新的资源。

    204 No Content:无内容。服务器成功处理,但未返回内容。一般用在只是客户端向服务器发送信息,而服务器不用向客户端返回什么信息的情况。不会刷新页面。

    206 Partial Content:服务器已经完成了部分GET请求。


    状态码开头为3,表示重定向。

    301 Moved Permanently:永久重定向,表示请求的资源已经永久的搬到了其他位置302 Found:临时重定向,表示请求的资源临时搬到了其他位置

    303 See Other:临时重定向,应使用GET定向获取请求资源。

    304 Not Modified:表示客户端发送附带条件的请求时,条件不满足。返回304时,不包含任何响应主体。

    307 Temporary Redirect:临时重定向。


    状态码开头为4,表示客户端请求有误。

    400 Bad Request:客户端请求有语法错误,服务器无法理解。

    401 Unauthorized:请求未经授权,此时需要进行认证。

    403 Forbidden:服务器收到请求,但是拒绝提供服务。

    404 Not Found:请求资源不存在。

    405 Method Not Allowed: 客户端请求中的方法被禁止。

    407 Proxy Authentication Required:与401类似,请求要求代理的身份认证,请求者应当使用代理进行授权。

    413 Precondition Failed:请求实体过大,服务器无法处理。常常在多文件上传或大文件上传中遇到。

    415 Unsupported media type:不支持的媒体类型。


    状态码开头为5,表示服务器端错误,服务器未能实现合法的请求。

    500  Internal Server Error  服务器内部错误,无法完成请求
    501  Not Implemented  服务器不支持请求的功能,无法完成请求
    503  Service Unavailable  由于超载或系统维护,服务器暂时的无法处理客户端的请求。
    505  HTTP Version not supported  服务器不支持请求的HTTP协议的版本,无法完成处理

  2. 响应头

    Date标头:消息产生的时间

    Age标头:(从最初创建开始)响应持续时间

    Server标头: 向客户端标明服务器程序名称和版本

    ETage标头:不透明验证者

    Location标头:URL备用的位置

    Content-Length标头:实体的长度

    Content-Tyep标头:实体的媒体类型

  3. 空行:发送回车符和换行符,通知浏览器以下不再有响应头。
  4. 响应体:包含了web服务端请求的对象。

HTTP请求跨域

由于同源策略,浏览器对JS实施了安全限制,只要协议,域名,端口任何一个不同,都会被当作不同的域.导致LocalStorage,SessionStorage,Cookie等浏览器内存无法跨域访问.Dom节点无法跨域操作、Ajax无法跨域请求.

解决方法

1.JSONP:由于script标签的src,img标签的src,link标签的href并不会被同源策略所限制,JSONP就借用了script标签的src,实现了跨域获取数据。JSONP是一个相对古老的解决跨域的方案,仅支持GET请求,需要前端后端共同实现。

2.WebSocket:由于设计原因,WebSock不附属于同源策略,它的跨域检测工作由服务端检测,服务器根据浏览器加上的Origin跨域请求头,判断此次WebSock是否合法.

3.Cors:跨域资源共享,需要由后端开启,开启后前端可跨域请求后端.

4.Node正向代理,利用服务端请求不会跨域的特性,让接口和当前站点同域,绕开同源策略.

5.Nginx反向代理,同Node代理相同,但是是由我们自己搭建一个中间服务.想要使用Nginx代理,我们需要下载Nginx.

6.window.postMessage,提供了一种受控机制,实现不同页面之间的数据传递.通常使用它进行页面和其打开的新窗口进行数据传递,多窗口之间的消息传递,页面于嵌套的iframe消息传递.

HTTP缓存策略

HTTP缓存策略有强缓存和协商缓存两种.

强缓存

在HTTP1.0版本里,强缓存使用的是Expires字段,HTTP1.1使用的是Cache-Control字段.

  • Expires

Expires是用于表示资源的过期时间的请求头字段,值是一个绝对时间,是由服务器端返回的。在这个过期时间之前可以直接从缓存里面获取数据,无需再次请求。由于expires是根据本地时间来判断的,倘若客户端和服务器时间不同,会导致缓存命中误差,因此在HTTP1.1版本中,提出了一个新的字段----Cache-Control.

  • Cache-Control

Cache-Control字段优先级高于Expires,在他的响应属性值max-age秒内,不与浏览器请求新的数据.倘若缓存数据失效,代表没有命中强缓存,进入协商缓存.

max-age:单位为秒,作用是设置缓存的存在时间,相对于发送请求的时间。只有响应报文首部设置Cache-control为非0的max-age或者设置了大于请求日期的Expires才有可能命中强缓存。当满足这个条件,同时响应报文首部中Cache-control不存在no-cache、no-store且请求报文首部不存在Pragma字段,才会真正命中强缓存。

no-cache:请求必须先行确定缓存的有效性。

no-store:表示禁止浏览器以及所有中间缓存存储任何版本的返回响应。

public:表明响应可以被浏览器、CDN等等缓存。

private:表明响应只作为私有的缓存,不能被CDN等缓存。

协商缓存

  • Last-Modified

Last-Modified是最后修改时间,在浏览器第一次给服务器发送请求后,服务器会在响应头中加上这个字段。如果再次请求,浏览器会在请求头中添加If-Modified-Since字段,如果该字段小于Last-Modified,则更新缓存,否则返回304,让浏览器直接使用缓存.

  • ETag

ETag是服务器根据当前文件的内容,对文件生成唯一的标识,服务器获取到标识的时候,与浏览器上的资源的ETag对比,如果改变,返回新值,没改变,返回304,让浏览器使用缓存.

HTTP优点与缺点

优点

  • 灵活可扩展:语法上仅仅规定了基本格式,传输的形式上不仅仅可以传输文本,还可以传输图像、文件等内容。
  • 传输可靠:基于TCP协议的HTTP协议,在传输的过程中同样继承了TCP的可靠性。
  • 无状态:因为无状态,所以就不需要额外的资源来记录状态信息,不仅实现上会简单一些,而且还能减轻服务器的负担,能够把更多的 CPU 和内存用来对外提供服务。

缺点

  • 无状态:在某些环境下,如商城等页面中,需要保存用户的信息,此时HTTP无状态的特性就给这一需求造成了困扰。
  • 明文传输:在http请求中,请求的数据常常能在url中以可阅读的文本的形式直接看见,这就造成了安全上的漏洞,容易被攻击者利用。
  • 队头阻塞:当http开启长连接时,共用一个TCP连接,当某个请求时间过长时,其他的请求只能处于阻塞状态,这就是队头阻塞问题。
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值