Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP演讲分享稿 #15

Open
linzx1993 opened this issue Apr 24, 2022 · 0 comments
Open

HTTP演讲分享稿 #15

linzx1993 opened this issue Apr 24, 2022 · 0 comments

Comments

@linzx1993
Copy link
Owner

前言:一道从上古流传至今的面试题:浏览器输入一个网址后发生了什么?

按键后的电路原理-》操作系统间的进程通信=》浏览器域名解析=》网络传输=》文件的解析与渲染

今天主要讲的是网络传输其中的一部分,HTTP应用层发出的请求,到传输层TCP/IP传输数据阶段

分享前瞻:

  1. HTTP各个版本增加了什么功能,做了哪些性能优化,仍然留下了什么缺陷?
  2. 浏览器是如何识别文件内容,并做对应的操作?
  3. 浏览器中的缓存是如何实现的?
  4. 浏览器如何与服务器配合 HTTP/2 ?为什么现在HTTP/2与3,仍然没有流行开来?
  5. 你知道HTTP中的队头堵塞问题吗?各个版本是怎么解决他们的呢?

1 HTTP请求

  1. 用户通过在浏览器输入网址并回车,或者是点击链接,接着浏览器获取了这个事件。(域名解析,编码规则)

  2. 浏览器向服务端发出 TCP 连接请求。(浏览器进程通信,网络寻址)

  3. 服务程序接受浏览器的连接请求,并经过 TCP 三次握手建立连接。(TCP握手)

4. 浏览器将请求数据打包成一个 HTTP 协议格式的数据包。( 请求

  1. 浏览器将该数据包推入网络,数据包经过网络传输,最终达到端服务程序。

6. 服务端程序拿到这个数据包后,同样以 HTTP 协议格式解包,获取到客户端的意图。

  1. 得知客户端意图后进行处理,比如提供静态文件或者调用服务端程序获得动态结果。

  2. 服务器将响应结果(可能是 HTML 或者图片等)按照 HTTP 协议格式打包。

  3. 服务器将响应数据包推入网络,数据包经过网络传输最终达到到到器。

10. 浏览器拿到数据包后,以 HTTP 协议的格式解包,然后解析数据,假设这里的数据是 HTML

  1. 浏览器将 HTML 文件展示在页面上。(前端渲染解析)

1.1 HTTP发展历史

1989年:HTTP协议诞生

1991 年:HTTP/0.9

GET /index.html
<html>
  
  <body>Hello World</body>
  
</html>

1、只有请求行(GET请求)

没有 HTTP 请求头和请求体。因为早期内容简单,读取超文本,只需要一个请求行就可以完整表达客户端的需求了。

2、服务器只返回数据,没有返回头信息,结果描述

3、返回的文件内容是 ASCII 字符

因为早期都是 HTML 格式的文件,所以使用 ASCII 字节码来传输是最合适的。

存在的问题:

1、时代发展,文件类型多样化(图片,音视频)

1993年:HTTP/1.0

1、增加了 HEAD、POST 等新方法

2、引入状态码,标记可能的错误原因

3、增加请求头和响应头:解决文件类型,编码类型

4、引入缓存机制(Expires)

GET /index.html HTTP1.1

HTTP/1.1 200 OK
HTTP/1.1 404 Not Found
accept: text/html
accept-encoding: gzip, deflate, br
accept-Charset: ISO-8859-1,utf-8
accept-language: zh-CN,zh

content-encoding: br
content-type: text/html; charset=UTF-8

1999年:HTTP/1.1

  1. 增加了持久连接:keep-alive
  2. 增加了PUT,DELETE,OPTIONS等方法
  3. 缓存相关请求头的增强
  4. cookie
  5. 支持动态生成的内容,断点续传
  6. 不成熟的 HTTP 管线化

  1. 浏览器设置域名最多同时维护 6-8个 TCP 持久连接
  2. 使用 CDN 的实现域名分片机制

仍未解决的问题:

  1. 请求头内容大于请求内容主体(参考GET请求)。
  2. 多条TCP连接,网速差时竞争宽带,影响关键资源传输
  3. 慢启动
  4. 队头阻塞问题

提问:

1、长连接是如何关闭的?

2、缓存请求头的优先级?

3、你知道

2015年:HTTP/2.0

1.多路复用

2.传输方式的优化:二进制的流(流标识符限定了流的总数,上限是 2^31)

3.头压缩:在双端建立key-value的索引表,发送请求头改为发送索引

4.设置请求的优先级

5.服务端的推送

一个域名只使用一个 TCP 长连接和消除队头阻塞问题。可以参考下图:

2.传输方式的优化:二进制的流(流标识符限定了流的总数,上限是 2^31)

3、请求头压缩:在双端建立key-value的索引表,发送请求头改为发送索引

进入到HTTP/2.0后, 前端会发生改变

1、文件打包的变化,例如:雪碧图,JS,CSS文件内联合并

仍未解决的问题

1、基于TCP协议的队头堵塞

当一个流中丢失了过多的包。场景:tcp层对每个数据包都有编号,分为1,2,3 .... tcp保证双向稳定可靠的传输,如果2包数据丢失,1号包和3号包来了,那么在超时重传时间还没有收到2编号数据包,服务端会发送2号数据包,客服端收到之后,发出确认,服务端才会继续发送其他数据,客服端数据才会呈现给上层应用层,这样tcp层的阻塞就发生了

2、IP 地址切换,重连TCP

TCP须重新建连,要再次“握手”,经历“慢启动”,而且之前连接里积累的 HPACK 字典也都消失了,必须重头开始计算,导致带宽浪费和时延。

3、单连接的容错率低于多个连接


提问:浏览器如何知道服务器支持 HTTP/2 呢?

答:TLS 的扩展里,有一个叫“ALPN”(Application Layer Protocol Negotiation)的东西,用来与服务器就 TLS 上跑的应用协议进行“协商”。

HTTP版本 功能 特点
0.9(1991) 1. 仅支持GET2. 服务器只能响应HTML形式字符串
1.0(1996) 1. 新增支持HEAD、POST2. 增加了响应状态码,标记可能的错误原因3. 引入了协议版本号概念4. 引入HTTP请求头概率5. 传输文本不再局限于文本 短连接存在HTTP线头阻塞问题
1.1(1997) 1. 新增支持PUT、DELETE等新的方法2. 增加了缓存管理与控制3. 明确了连接管理,支持持久连接4. 加入了管道(pipelining)机制(浏览器默认不开启)5. 强制加入HOST请求头6. 支持断点续传 是目前互联网上使用最广泛的协议,功能也非常完善存在服务器HTTP线头阻塞问题,常浏览器允许对一个HOST最多建立6个TCP连接,在这6个中发送HTTP请求(诞生了域名分片技术)
2.0(2015) 1. 废弃pipeline,使用多路复用机制(数据流进行串行传输)2. 采用二进制分帧,不再是纯文本3. 支持首部压缩(HPATCH)4. 支持服务器推送5. 增强了安全性,“事实上”要求加密通信 一个HOST只建立一个TCP连接,解决了HTTP线头阻塞,但依然存在TCP线头阻塞问题

2018年- HTTP/3.0(HTTP over QUIC)

基于UDP协议的伪TCP协议

1、支持无缝切换网络

2、队头阻塞问题

HTTP2.0的各个流有互相依赖关系,如果前面一个流丢失了,后面被迫阻塞

举例:一个包内包含了某个js的部分内容,如果丢失,包含其余js的包被迫等待缓存在那里

1.2 http请求头解析

概念名词:请求头,响应头,RTT,TTL

请求行 请求头 请求体

请求头

请求头不分大小写

长连接请求头

Connection: keep-alive

Connection: close

Content-Type

content-type类型,遵循传统MIME type的类型:标记数据类型
MIME type:标记数据类型、

  1. text:即文本格式的可读数据,典型就是 text/html 了,表示超文本文档,此外还有纯文本text/plain、样式表 text/css 等。
  2. image:图像文件,有 image/gif、image/jpeg、image/png 等。
  3. audio/video:音频和视频数据,例如 audio/mpeg、video/mp4 等。
  4. application:数据格式不固定,可能是文本也可能是二进制,必须由上层应用程序来解释。常见的有 application/json,application/javascript、application/pdf 等。如果实在是不知道数据是什么类型,像刚才说的“黑盒”,就会是 application/octet-stream,即不透明的二进制数据。

根据不同的类型做不同的操作

  • 比如zip等,浏览器会调用下载进程
  • 比如html,css文件,浏览器会根据不同type进行解析渲染
  • 比如image和audio,会请求传输静态资源

Encoding type: 标记压缩编码格式

  1. gzip:GNU zip 压缩格式,也是互联网上最流行的压缩格式;
  2. deflate:zlib(deflate)压缩格式,流行程度仅次于 gzip;
  3. br:一种专门为 HTTP 优化的新压缩算法(Brotli)。

缓存

Cache-control

微店链接

  1. 强缓存:max-age (200 OK (from disk cache)))
  2. 协商缓存:no-cache (304)

if-Modified-Since :Last-modified

If-None-Match :ETag

  1. 不缓存

cookie

cookie

自定义请求头

location / {  
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'Souche-Security-Token,X-Souche-ServiceChain,If-Modified-Since,Cache-Control,Content-Type,Authorization';

    if ($request_method = 'OPTIONS') {
        return 204;
    }
} 

1.3 HTTP中队头阻塞的演进史

什么是队头阻塞(Head-of-Line blocking)?

当单个(慢)对象阻止其他/后续的对象前进时

HTTP/1.1 的队头阻塞

只请求一个JS文件

111111

同时请求一个JS文件和CSS文件

111111 22

1121121


function first() { return "hello"; }
HTTP/1.1 200 OK
Content-Length: 600

.h1 { font-size: 4em; }
func

HTTP/2(基于 TCP)的队头阻塞

我们希望能够正确地复用资源块(resource chunks)

HTTP/3(基于 QUIC)的队头阻塞

  • HTTP/1.1 有队头阻塞,因为它需要完整地发送响应,并且不能多路复用它们
  • HTTP/2 通过引入“帧”(frames)标识每个资源块属于哪个“流”(stream)来解决这个问题
  • 然而,TCP 不知道这些单独的“流”(streams),只是把所有的东西看作一个大流(1 big stream)
  • 如果一个 TCP 包丢失,所有后续的包都需要等待它的重传,即使它们包含来自不同流的无关联数据。TCP 具有传输层队头阻塞。

2.TCP

TCP报文头

慢启动,拥塞算法,快重传,传输控制算法

参考文章链接

透视HTTP协议

QUIC 和 HTTP/3 队头阻塞的细节

拥塞控制视频版讲解

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant