HTTP性能、服务器推送

主要内容:

  1. SPDY是什么
  2. WebSocket是什么
  3. HTTP2.0
  4. 服务器推送方法,短轮询、长轮询(comet)是什么

HTTP1.0

一次请求:客户端与服务器建立TCP连接,发送请求接收响应,关闭连接

发送请求一份包含多张图片的HTML文档对应的Web页面需要和服务器通信多次,产生开销极大

最主要的问题是:一次请求一次响应(对应一个资源)

HTTP1.1(1997)

改进1:连接可以复用。一次连接,多个请求响应(对应多个资源)(设置keep-alive
改进2:增加流水线操作。下一个请求不需要等待上一个请求完成(得到响应)再发送,但是响应顺序不变(FIFO)
其它:支持响应分;引进额外的缓存控制机制;引入内容协商机制,包括语言、编码类型等(请求类型扩展、状态码扩展、分块加载资源)

问题:

  1. 每个域名下的请求有数量限制(约6),超过限制的请求会被阻塞(一些网站使用多个域名来管理静态资源,但是过多的域名管理不变且域名解析也需要时间)
  2. 只能客户端主动发起请求,服务器不能主动发起
  3. 请求、响应头都太大,未经压缩直接发送,浪费网络资源
  4. 请求、响应头大部分内容都是冗余
  5. 数据压缩非强制,所以可能有未压缩的情况
  6. 请求顺序没有优先级,只能按照HTML资源顺序
  7. 客户端可以解析html发送资源请求,服务器也行(后台可以主动发送)
  8. 更多

SPDY(Google 2010-2015)

发音寓意同 speedy

只能Https使用

  1. 基于二进制流,将一个TCP连接分为若干流(stream),每个流中可以传输若干信息(message),每个消息由若干最小的二进制帧(frame)组成(争议:基于二进制流像是传输层协议做的事情,因为将应用层的内容做可靠性传输是传输层的工作)
  2. 多路复用(multiplexing),一个TCP连接可以处理无限请求(无限制处理多个请求)
  3. 压缩http头
  4. 服务器推送(server push)客户端发送获取html的请求,服务器把html和html里面所有的资源发过来
  5. 服务器提示(server hints)<link rel=prefetch src=xxx>浏览器会在空闲时间加载这个大的图片,下次请求可能会用到
  6. 请求可以设置优先级

HTTP2.0

SPDY于2015年停用,演化为HTTP2.0

  1. 新增头部加密算法
  2. 非https也能用

使用SPDY/HTTP2.0只需要设置服务器即可,如果用户浏览器不支持,那么会自动使用老协议来服务

双工通信--服务器推送

以聊天举例

Ajax轮询

浏览器设置一个时间间隔来无限访问服务器获取数据,一旦服务器的聊天记录列表更新了,那么浏览器(客户端)可以获得最新的数据并且渲染页面

优点:代码简单
缺点:间隔太长,延迟高,间隔太短,性能问题

Comet--长轮询

在发送一个请求后,得到响应再发送一个请求,在等待的过程中是节省性能的。在服务端需要判断,只有聊天记录更新才会给响应,否则只把请求保存下来(请求队列),当有新数据进来,开始响应所有请求

对短轮询的补足,但轮询都不是真正的服务器推送

WebSocket

浏览器创建websocket,先创建一个http请求,请求url是ws:开头,服务器会返回101状态码(转换协议)-- 演示翻车了

Wiki内容简单翻译

WebSocket是一个计算机通信协议,在一个TCP连接上提供全双工通信通道。WebSocket协议在2011年被IETF标准化(RFC6455),在Web IDL上的WebSocket API被W3C标准化

它们都是应用层协议,虽然它们不同,但是RFC6455声明“WebSocket是设计用来在HTTP端口(443、80)上工作的且支持HTTP协议并且是可以互操作的”。要实现这个兼容性,WebSocket的握手使用HTTP Upgrade header来从HTTP协议转换为WebSocket协议

WebSocket协议允许客户端和服务器在比HTTP这种半双工通信的负载低的情况下做交互,可以实时在服务器收发数据。这使得实现在客户端不发请求的情况下服务器推送数据的标准化方式成为可能,在保持连接的情况下,允许信息的来回发送。这个连接通常在TCP端口号443(不安全的连接80端口)上进行,它利用了防火墙会阻塞非web(其它端口)的网络连接

WebSocket解决的是之前的Comet实现方式不实用(nontrivial),并且TCP握手和HTTP头的内容都很冗余在信息量不大的情况下出现的问题

ws(WebSocket)和wss(WebSocket Secure)作为两种新的URI用来解密和加密连接

协议握手

要建立WebSocket连接,客户端发送一个WebSocket握手请求,浏览器返回一个WebSocket握手响应

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

这个握手允许服务器可以处理HTTP连接和WebSocket连接(在同一个端口),一旦连接建立,通信变为双向二进制协议。除了Upgrade头,客户端还发送了Sec-WebSocket-Key头,包括base64编码的随机字节,服务器在Sec-WebSocket-Accept头中加入这个内容的散列值,这是为了防止从重发之前的WebSocket转换的缓存协议,并且不提供任何认证、隐私或者集成(integrity)

一旦连接建立,客户端和服务器可以以全双工模式来发送WebSocket数据或者text帧。数据尽可能小地转为帧,在payload之后有一个小的头信息。WebSocket传输的内容即message,单个信息可以被分为多个数据帧。这使得允许发送开头的数据已经得到但是数据长度未知的数据。通过这个协议的扩展,可以用来通过发送多个流

WebSocket请求并没有被限制Same-origin,因此WebSocket服务器在建立连接时必须验证Origin头,来避免跨站WebSocket劫持攻击(cross-site websocket hijacking attack--类似csrf),在发送隐私数据时最好使用token或类似机制来做鉴权

posted on 2021-01-18 17:08  老鼠不上树  阅读(201)  评论(0)    收藏  举报