notes
  • Introduction
  • 前言
  • javascript
    • bind, call, apply 总结
    • Promise 总结
    • 事件循环(EventLoop)
    • 迭代器与生成器
    • 原型与原型链和继承
    • 函数防抖与函数节流
    • 性能优化需要知道的基础知识(HTTP)
    • 函数柯里化与反柯里化
  • react
    • Redux 小结
  • 其他
    • 资源推荐
    • DNS、Host、VPN 和科学上网
    • 脱坑手册
    • 安全
    • 正则表达式
    • 基于 rsync 同步文件
Powered by GitBook
On this page
  • 从 URL 输入到页面展现到底发生了什么?
  • DNS 解析查找过程
  • TCP 特性
  • TCP 三次握手
  • SYN 攻击
  • 浏览器解析渲染页面
  • TCP 四次挥手
  • HTTP 的发展变化
  • HTTP1.0 和 HTTP1.1 的区别
  • HTTP2.0 新特性
  • HTTPS
  • 常见的状态码
  • 性能优化实践

Was this helpful?

  1. javascript

性能优化需要知道的基础知识(HTTP)

**HTTP 协议是建立在 TCP 协议之上的应用层协议所以 HTTP 协议的瓶颈及其优化都是基于 TCP 协议本身的特性的**

从 URL 输入到页面展现到底发生了什么?

总体来说分为以下过程

  • DNS 解析: 将域名解析成 IP 地址

  • TCP 链接: TCP 三次握手

  • 发送 HTTP 请求

  • 服务器处理请求并返回 HTTP 报文

  • 浏览器解析渲染页面

  • 断开连接:TCP 四次挥手

DNS 解析查找过程

  • 浏览器缓存>操作系统缓存>路由缓存>ISP 的 DNS 服务器>根服务器

TCP 特性

  • TCP 是一种无状态的、面向连接的、可靠的字节流服务

  • 在一个 TCP 连接中,仅有两方进行彼此通信。广播和多播不能用于 TCP

  • TCP 使用校验和,确认和重传机制来保证可靠传输

  • TCP 给数据分节进行排序,并使用累积确认保证数据的顺序不变和非重复

  • TCP 使用滑动窗口机制来实现流量控制,通过动态改变窗口的大小进行拥塞控制

注意:TCP 并不能保证数据一定会被对方接收到,TCP 能够做到的是,如果有可能,就把数据递送到接收方,否则就(通过放弃重传或者中断连接这一手段)通知用户。因此准确说 TCP 也不是 100% 可靠的协议,它所能提供的是数据的可靠递送或故障的可靠通知。

TCP 三次握手

  • 第一次握手,客户端发送连接请求到服务端 SYN=1, seq=x ; 客户端进入 SYN_SEND 状态,等待服务器的确认

  • 第二次握手,服务端响应请求 SYN=1, ACK=1, seq=y, ack=x+1; 服务器进入 SYN_RECV 状态

  • 第三次握手,客户端响应服务器 ACK=1, seq=x+1, ack=y+1; 客户端和服务器端都进入 ESTABLISHED 状态

"三次握手"总共经历:请求---应答---再次确认,目的是为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

举个栗子:

“已失效的连接请求报文段”的产生在这样一种情况下:client 发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达 server。本来这是一个早已失效的报文段。但 server 收到此失效的连接请求报文段后,就误认为是 client 再次发出的一个新的连接请求。于是就向 client 发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要 server 发出确认,新的连接就建立了。由于现在 client 并没有发出建立连接的请求,因此不会理睬 server 的确认,也不会向 server 发送数据。但 server 却以为新的运输连接已经建立,并一直等待 client 发来数据。这样,server 的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client 不会向 server 的确认发出确认。server 由于收不到确认,就知道 client 并没有要求建立连接。

SYN 攻击

**什么是 SYN 攻击?**

在三次握手过程中,服务器发送 SYN-ACK 之后,收到客户端的 ACK 之前的 TCP 连接称为半连接(half-open connect)。此时服务器处于 SYN_RCVD 状态。当收到 ACK 后,服务器才能转入 ESTABLISHED 状态。SYN 攻击指的是,攻击客户端在短时间内伪造大量不存在的 IP 地址,向服务器不断地发送 SYN 包,服务器回复确认包,并等待客户的确认。由于源地址是不存在的,服务器需要不断的重发直至超时,这些伪造的 SYN 包将长时间占用未连接队列,正常的 SYN 请求被丢弃,导致目标系统运行缓慢,严重者会引起网络堵塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。

**如何检测 SYN 攻击?**

检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源 IP 地址是随机的,基本上可以断定这是一次 SYN 攻击。在 Linux/Unix 上可以使用系统自带的 netstats 命令来检测 SYN 攻击。

**如何防御 SYN 攻击?**

SYN 攻击不能完全被阻止,除非将 TCP 协议重新设计。我们所做的是尽可能的减轻 SYN 攻击的危害,常见的防御 SYN 攻击的方法有如下几种:

  • 缩短超时(SYN Timeout)时间

  • 增加最大半连接数

  • 过滤网关防护

  • SYN cookies 技术

浏览器解析渲染页面

  • 根据 HTML 解析出 DOM 树

  • 根据 CSS 解析生成 CSS 规则树

  • 结合 DOM 树和 CSS 规则树,生成渲染树

  • 根据渲染树计算每一个节点的信息

  • 根据计算好的信息绘制页面

根据 HTML 解析 DOM 树

  • DOM 树解析的过程是一个深度优先遍历。即先构建当前节点的所有子节点,再构建下一个兄弟节点。

  • 在读取 HTML 文档,构建 DOM 树的过程中,若遇到 script 标签,则 DOM 树的构建会暂停,直至脚本执行完毕。

根据 CSS 解析生成 CSS 规则树

  • 解析 CSS 规则树时 js 执行将暂停,直至 CSS 规则树就绪。

  • 浏览器在 CSS 规则树生成之前不会进行渲染。

结合 DOM 树和 CSS 规则树,生成渲染树

  • DOM 树和 CSS 规则树全部准备好了以后,浏览器才会开始构建渲染树。

  • 精简 CSS 可以加快 CSS 规则树的构建,从而加快页面相应速度。

根据渲染树计算每一个节点的信息(布局)

  • 布局:通过渲染树中渲染对象的信息,计算出每一个渲染对象的位置和尺寸

  • 回流:在布局完成后,发现了某个部分发生了变化影响了布局,那就需要倒回去重新渲染。

根据计算好的信息绘制页面

  • 绘制阶段,系统会遍历呈现树,并调用呈现器的“paint”方法,将呈现器的内容显示在屏幕上。

  • 回流:某个元素的尺寸发生了变化,则需重新计算渲染树,重新渲染。

  • 重绘:某个元素的背景颜色,文字颜色等,不影响元素周围或内部布局的属性,将只会引起浏览器的重绘。

TCP 四次挥手

客户端或服务器均可主动发起挥手动作, 举个栗子:

  • 第一次挥手:Client 发送一个 FIN,用来关闭 Client 到 Server 的数据传送,Client 进入 FIN_WAIT_1 状态。

  • 第二次挥手:Server 收到 FIN 后,发送一个 ACK 给 Client,Server 进入 CLOSE_WAIT 状态。

  • 第三次挥手:Server 发送一个 FIN,用来关闭 Server 到 Client 的数据传送,Server 进入 LAST_ACK 状态。

  • 第四次挥手:Client 收到 FIN 后,Client 进入 TIME_WAIT 状态,发送 ACK 给 Server,Server 进入 CLOSED 状态

简单来说:Client 表示没有数据要传输给 Server,Server 应答这次请求(这个时候 Server 可能还有数据要传输给 Client,只是单方面关闭 Client 到 Server 的数据传输通道),Server 表示没有数据给 Client,Client 应答这次请求,总共经历四次挥手

HTTP 的发展变化

HTTP1.0 和 HTTP1.1 的区别

  • 长连接,HTTP 1.1 支持长连接(PersistentConnection)和 HTTP 管线化(Pipelining)处理,在一个 TCP 连接上可以传送多个 HTTP 请求和响应,减少了建立和关闭连接的消耗和延迟。HTTP1.1 默认支持长连接。HTTP1.1 在同一时间对于同一个域名的请求数量有限制,超过限制就会阻塞请求

  • 节约带宽,HTTP1.0 中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1 则在请求头引入了 range 头域,它允许只请求资源的某个部分,即返回码是 206(Partial Content),这是支持文件断点续传的基础。支持只发送 header 信息,可以用作权限请求。

  • 错误通知的管理,在 HTTP1.1 中新增了 24 个错误状态响应码,如 409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。

  • HOST 域,在 HTTP1.0 中认为每台服务器都绑定一个唯一的 IP 地址,因此,请求消息中的 URL 并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个 IP 地址。HTTP1.1 的请求消息和响应消息都应支持 Host 头域,且请求消息中如果没有 Host 头域会报告一个错误(400 Bad Request)。

HTTP2.0 新特性

  • 二进制分帧:HTTP 2.0 性能增强的核心,在应用层与传输层之间增加一个二进制分帧层,以此达到“在不改动 HTTP 的语义,HTTP 方法、状态码、URI 及首部字段的情况下,突破 HTTP1.1 的性能限制,改进传输性能,实现低延迟和高吞吐量。在二进制分帧层上,HTTP2.0 会将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码,其中 HTTP1.x 的首部信息会被封装到 Headers 帧,而我们的 request body 则封装到 Data 帧里面。客户端和服务器可以把 HTTP 消息分解为互不依赖的帧,然后乱序发送,最后再在另一端把它们重新组合起来。

  • 多路复用:做到同一个连接并发处理多个请求。HTTP2.0 使用 HPACK 算法对 header 的数据进行压缩。

  • 头部压缩:在 HTTP1.x 中,首部元数据都是以纯文本形式发送的,通常会给每个请求增加 500~800 字节的负荷。为减少这些开销并提升性能,HTTP 2.0 会压缩首部元数据。

  • 服务器推送

HTTPS

基于 HTTP 协议,通过 SSL 或 TLS 提供加密处理数据、验证对方身份以及数据完整性保护。

实现原理流程:

  • 客户端向服务端发送请求

  • 服务端把数字证书发送给客户端:数字证书包含的信息有证书的办法机构,过期时间,服务端的公钥,服务端的域名信息,以及证书颁发机构的签名等内容

  • 客户端解析证书,这部分工作是 SSL/TLS 来完成,首先使用证书的公钥进行验证签名,确保证书的真实有效,如果证书没问题那么就生成一个秘钥(对称加密),然后使用证书里面解析出来的服务端公钥对该秘钥进行加密,然后传输给服务端。

  • 服务端通过私钥解密,得到客户端传输过来的私钥信息

  • 客户端与服务器进入加密通信,就完全是使用普通的 HTTP 协议,只不过用"密钥"加密内容。

数字签名:对内容进行 hash 运算生成摘要(digest)然后使用私钥对摘要进行加密生成签名(signature),签名是为了保证信息的真实性和完整性

常见的状态码

  • 200 OK 客户端请求成功

  • 301 Moved Permanently 请求永久重定向

  • 302 Moved Temporarily 请求临时重定向

  • 304 Not Modified 文件未修改,可以直接使用缓存的文件。

  • 400 Bad Request 由于客户端请求有语法错误,不能被服务器所理解。

  • 401 Unauthorized 请求未经授权。这个状态代码必须和 WWW-Authenticate 报头域一起使用

  • 403 Forbidden 服务器收到请求,但是拒绝提供服务。服务器通常会在响应正文中给出不提供服务的原因

  • 404 Not Found 请求的资源不存在,例如,输入了错误的 URL

  • 500 Internal Server Error 服务器发生不可预期的错误,导致无法完成客户端的请求。

  • 503 Service Unavailable 服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常。

性能优化实践

  • 减少 HTTP 请求数

  • 避免重复的资源请求:这种情况主要是由于疏忽或页面由多个模块拼接而成,然后每个模块中请求了同样的资源时,会导致资源的重复请求

  • 减少 DNS 查找

  • 重用 TCP 连接

  • 减少 HTTP 重定向。HTTP 重定向需要额外的 DNS 查询、TCP 握手等非常耗时,最佳的重定向次数为 0

  • 使用 CDN(内容分发网络):把数据放在离用户地理位置更近的地方,可以明显减少每次 TCP 连接的网络延迟

  • 缓存必要的应用资源,避免每次都重复请求相同的内容

  • 传输数据之前应该先压缩应用资源,把要传输的字节减少到最小,在压缩的时候确保对每种不同的资源采用最好的压缩手段

  • 消除不必要的请求开销:减少请求的 HTTP 首部数据(比如 HTTP cookie)

  • 并行处理请求和响应

Previous函数防抖与函数节流Next函数柯里化与反柯里化

Last updated 5 years ago

Was this helpful?

TCP 三次握手
TCP 四次挥手