zoukankan      html  css  js  c++  java
  • 基于HTTP的一些追加协议SPDY, Comet, Http2.0

    HTTP的瓶颈

    • 使用http协议探知服务器上是否有内容更新,就必须频繁地从客户端到服务端进行确认,会产生徒劳的通信
    • 一条连接上只能发送一个请求
    • 请求只能从客户端开始,客户端不可以接收除响应以外的指令。
      • 单向请求。注定了如果服务器有连续状态变化,客户端要获知就很麻烦。
      • 因此只能使用轮询,效率就很低,浪费资源(必须不断连接,或者HTTP连接始终打开)
    • 请求/响应首部未经压缩就发送。首部信息越多,延迟越大。
    • 发送冗长的首部。每次相互发送相同的首部造成的浪费较多。
    • 可任意选择数据压缩格式。非强制压缩发送。
    • img

    Ajax和Comet的解决方法

    • 非协议上的改动

    Ajax

    • Asynchronous JavaScript and XML,异步Javascript与XML技术
    • Ajax是一种有效利用Javascript和Dom的操作,以达到局部Web页面替换的异步通信操作。
    • 通过Javascript的调用就可以和服务器进行HTTP通信,借由这种手段,就能从已加载完毕的Web页面上发起请求,只更新局部页面。

    img

    Comet

    • 一旦服务器端有内容更新了,Comet不会让请求等待,而是直接给客户端返回响应。这是一种通过延迟应答,模拟实现服务端向客户端推送Server Push
    • 为实现推送功能,Comet会先将响应置于挂起状态,当服务器有内容更新时,再返回该响应。因此,服务端一旦有更新,就能立即反馈给1客户端。
    • 为了保持响应,一次连接的持续时间也会变长了,期间,为了维持连接会消耗更多的资源。
    • 并未解决HTTP协议本身的问题

    消除HTTP瓶颈的SPDY

    • SPeeDY
    • 是协议层面的改动,处于持续开发状态中的SPDY协议,用于协议层面消除HTTP瓶颈
    • TCP/IP的应用层与运输层之间通过新加会话层的形式也运作。
    • 考虑到安全性,SPDY规定通信中使用SSL
    • 缺点:SPDY基本上只是将单个域名(IP地址)的通信多路复用,所以当一个Web网站上使用多个域名下的资源,改善效果就会收到限制

    HTTP将获得的功能

    • 多路复用流:通过单一的TCP连接,可以无限制处理多个HTTP请求
    • 赋予请求优先级:SPDY不仅可以无限制地并发处理请求,而且可以给请求逐个分配优先级顺序。
    • 压缩HTTP首部:请求和响应首部压缩
    • 推送功能:支持服务器主动向客户端推送数据的功能。这样服务器可以直接发送数据,而不必等待客户端的请求。
    • 服务器请求功能:服务器可以主动提示客户端请求所需的资源。

    WebSocket

    • 也是协议层上解决HTTP的瓶颈
    • WebSocket即Web浏览器与Web服务器之间全双工通信标准
    • Javascript可以调用The WebSocket API

    协议概述

    • 一旦Web服务器与客户端建立起WebSocket的通信连接,之后的所有通信都依靠这个专用协议进行。
    • 由于是建立再HTTP基础上的协议,因此连接的发起方仍是客户端。而一旦确立WebSocket通信连接,不论是客户端还是服务端,任意一方副都可以直接向对方发送报文
    • 推送功能:支持服务器向客户端推送数据的推送功能
    • 减少通信量:只要建立Websocket连接,就希望一直保持连接状态。

    Http和WS区别

    • 相同:
      • 都是基于TCP的应用层协议;
      • 都使用Request/Response模型进行连接的建立;
      • 在连接的建立过程中对错误的处理方式相同,在这个阶段WS可能返回和HTTP相同的返回码
      • 都可以在网络中传输数据
    • 不同
      • WS使用HTTP来建立连接,但是定义了一系列新的header域,这些域在HTTP中并不会使用;
      • WS的连接不能通过中间人来转发,它必须是一个直接连接
      • WS连接建立之后,通信双方都可以在任何时刻向另一方发送数据;
      • WS连接建立之后,数据的传输使用帧来传递,不再需要Request消息
      • WS的数据帧有序

    通信过程

    imgimg

    报文

    客户端握手请求

    • GET / HTTP/1.1
      Upgrade: websocket
      Connection: Upgrade
      Host: example.com
      Origin: http://example.com
      Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
      Sec-WebSocket-Protocol: chat, superchat
      Sec-WebSocket-Version: 13
      
    • 握手请求:为了实现WebSocket,再HTTP连接建立之后,要完成一次握手

    • 字段

      • Upgrade首部字段,告知服务器通信协议发生变化,以达到握手的目的
      • Connection: Upgrade(必须包含) 与 Upgrade字段(必须包含):表示发起的是WebSocket协议
      • Origin(请求头):Origin用来指明请求的来源
        • Origin头部主要用于保护WebSocket服务器免受非授权的跨域脚本调用WebSocket API的请求。
        • 也就是不想没被授权的跨域访问与服务器建立连接,服务器可以通过这个字段来判断来源的域并有选择的拒绝。
      • Sec-WebSocket-Key字段:记录着握手过程中必不可少的键值,是由浏览器随机生成的,提供基本的防护,防止恶意或者无意间的连接
      • Sec-WebSocket-Protocol:记录使用的子协议,定义那些连接的名称
      • Sec-WebSocket-Version:表示WS的版本
        • 最初WS协议太多,各个厂商都有自己的协议,现在已经定下来了。
        • 如果服务端不支持该版本,就需要返回Sec-WebSocket-Versionheader,里面包含服务器支持的版本号

    服务器握手响应

    • HTTP/1.1 101 Switching Protocols
      Upgrade: websocket
      Connection: Upgrade
      Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
      Sec-WebSocket-Protocol: chat
      
    • 握手响应

      • 返回状态码101 Switching Protocols
      • Sec-WebSocket-Accept:由握手请求中的Sec-WebSocket-Key的字段值生成的。(加密过的Sec-WebSocket-Key),计算方法如下:
        • 将Sec-WebSocket-Key跟 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 拼接;
        • 通过 SHA1 计算出摘要,并转成 base64 字符串。
        • Sec-WebSocket-Key/ Sec-WebSocket-Accept的换算只能带来基本的保障,但连接是否安全,数据是否安全,客户端/服务端是否合法的WS客户端,WS服务端,并没有实际性保证
      • Sec-WebSocket-Protocol:记录使用的子协议,定义那些连接的名称
      • 之后便采用WebSocket独立的数据帧。

    帧格式

    img

    • FIN:是否为消息的最后一个分片,1b
      • 0:不是消息
      • 1:是消息的最后一个分片
    • RSV1,RSV2,RSV3,各1b
      • 一般情况下都是0
      • 当客户端、服务端协商采用WebSocket扩展时,这三个标志位可以非0,且值的含义由扩展进行定义。
      • 如果出现非0的值,而且并没有采用WebSocket扩展,连接出错。
    • Opcode:4b
      • %x0:表示一个延续帧,表示本次数据传输采用了数据分片,当前收到的数据帧为其中一个数据分片。
      • %x1:表示这是一个文本帧
      • %x2:表示这是一个二进制帧
      • %x3-7:保留的操作码,用于后续定义的非控制帧
      • %x8:表示连接断开
      • %x9:表示这是一个ping操作
      • %xA:表示这是一个pong操作
      • %xB-F:保留的操作码,用于定义后续的控制帧
    • Mask:1b
      • 表示是否要队数据载荷进行掩码异或操作
      • 0:No
      • 1:Yes
    • Payload Length:7b or 7+16b or 7+64b
      • 表示数据载荷的长度
      • x为0~126:数据的长度为x字节
      • x为126(111 1110):后续2个字节(16b)代表一个16b的无符号整数,该无符号整数的值为数据的长度
      • x为127(111 1111):后续8个Byte(64b)代表一个64b的无符号整数,该无符号整数的值为数据的长度
    • Masking-Key:0 or 4Bytes
      • 若Mask=0: 没有Masking-Key
      • 若Mask=1:则携带了4B(32b)的Masking-key
      • PS:掩码的作用不是为了防止数据泄露,而是为了防止早期版本中的协议中存在的代理缓存污染攻击(Proxy cache poisoning attacks)等问题
    • Payload Data:载荷数据
      • 真正要发送的数据,虽然理论上帧的大小没有限制,但是发送的数据不能太大,否则会导致无法高效利用网络带宽,WS提供分片

    总结

    • 没有其他能像 WebSocket 一样实现双向通信的技术了,迄今为止,大部分开发者还是使用 Ajax 轮询来实现,但这是个不太优雅的解决办法,WebSocket 虽然用的人不多,可能是因为协议刚出来的时候有安全性的问题以及兼容的浏览器比较少,但现在都有解决。如果你有这些需求可以考虑使用 WebSocket:
      • 多个用户之间进行交互;
      • 需要频繁地向服务端请求更新数据。
      • 比如弹幕、消息订阅、多玩家游戏、协同编辑、股票基金实时报价、视频会议、在线教育等需要高实时的场景。

    HTTP2.0

    什么是HTTP2.0

    • 对http1.x协议语义的完全兼容
    • 目标是改善用户在使用Web时的速度体验。新能大幅提升。
    • SPDY与HTTP2.0主要区别
      • HTTP2.0 支持明文http传输,而SPDY强制使用HTTPS
      • HTTP2.0 消息头的压缩算法采用HPACK,而SPDY采用DEFLATE

    HTTP2.0 优化内容

    • 实现方法:

      • SPDY:
      • HTTP Speed + Mobility : 用于改善并提高移动端通信时的通信速度和性能指标,建立在SPDY与WebSocket的基础之上
      • Network-Friendly HTTP Upgrade:主要时在移动端通信时改善HTTP性能标准
    • HTTP/2.0主要的7项技术

      • 压缩 SPDY, Friendly
        多路复用 SPDY
        TLS义务化 Speed+Mobility
        协商 Speed+Mobility, Friendly
        客户端拉拽(Client Pull)/服务器推送(Server Push) Speed+Mobility
        流量控制 SPDY
        WebSocket Speed+Mobility

    二进制分帧(Binary Format)-- http2.0的基石

    • 帧包含:
      • Type 类型
      • Length 长度
      • Flags 标记
      • Stream 流标识
      • frame payload 有效载荷
    • 消息:一个完整的请求或响应,由一个or多个帧组成
    • 流是连接中的一个虚拟信道,可以承载双向消息传输
      • 每个流具有唯一的整数标识符
      • 为了防止两端ID冲突:
        • 客户端发起的流具有奇数ID
        • 服务端发起的流具有偶数ID
      • 一个http2连接上可以包含多个并发打开的流,这个并发流的数量能够由客户端设置
    • 在二进制分帧层上,http2会将所有传输信息分割为更小的消息和帧,并对他们采用二进制格式的编码,将其封装。
      • 兼容上一代http
      • http1.x的首部信息header封装到Headers帧中
      • http1.x的request body被封装到Data帧中
    • img

    多路复用(Multiplexing)/ 连接共享

    • 允许同时通过单一的http/2连接发起多重的请求-响应消息
    • 有了新的分帧机制后,http/2不再依赖多个tcp连接去实现多流并行了
    • 每个数据流都拆分成很多个互不依赖的帧,这些真可以交错(乱序)发送,还可以分优先级,然后在另一端根据不同帧首部的流标识符再重新组合起来。
    • http2.0的连接都是持久化的,客户端与服务器之间只需要以一个链接(每个域名一个连接)
    • img
    • img

    头部压缩(Header Compression)

    • http2使用encoder来减少需要传输的header大小,通讯双方各自缓存一份头部字段表,既避免了重复header的传输,又减小需要传输的大小。
    • 对于相同的数据,不再通过每次请求和响应发送,通信期间几乎不会改变通用键-值对(用户代理、可接受的媒体类型等等),只需要发送一次
    • 如果请求中不包含首部(ex:对同一资源的轮询请求),那么首部开销就是0字节,此时所有首部都自动使用之前请求发送的首部
    • 如果首部发生变化,则只需要将变化的部份加入到header帧中,改变的部份会加到头部字段表中,首部表在http2的连续存续期内始终存在,由客户端和服务端共同渐进地更新
    • http 2.0关注的是首部压缩,而我们常用的gzip等是报文内容(body)的压缩,二者不仅不冲突,且能够一起达到更好的压缩效果。
    • http2.0使用的专门为首部压缩设计的HPACK算法

    压缩原理

    • 使用header字段表里的index代替实际的header
    • HPACK使用
      • 一份索引表来定义常用的http header,请求时只需要发送在表里的索引位置即可
      • 将字符串进行哈夫曼编码来压缩字符串大小
    • 因为索引表的大小的是有限的,它仅保存了一些常用的 http Header,同时每次请求还可以在表的末尾动态追加新的 http Header 缓存,动态部分称之为 Dynamic Table。Static Table 和 Dynamic Table 在一起组合成了索引表
    • 以常用的 User-Agent 为例,它在静态表中的索引值是 58,它的值是不存在表中的,因为它的值是多变的。第一次请求的时候它的 key 用 58 表示,表示这是一个 User-Agent ,它的值部分会进行霍夫曼编码(如果编码后的字符串变更长了,则不采用霍夫曼编码)。
    • 服务端收到请求后,会将这个 User-Agent 添加到 Dynamic Table 缓存起来,分配一个新的索引值。客户端下一次请求时,假设上次请求User-Agent的在表中的索引位置是 62, 此时只需要发送 0xBE(同样的,高位置 1),便可以代表:User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36。
    • img
    • 高位设置为1表示这个字节是一个完全索引值(key和value都在索引中)

    请求优先级(Request Priorities)

    • 每个流可以带有一个31b的优先值:
      • 0:最高
      • (2^{31}-1)最低
    • 优先将最高优先级的帧发送给客户端,高优先级的流都应该优先发送,但并不绝对。
    • 分配处理资源和用户与服务器的宽带,不同优先级的混合也是必须的。客户端会指定哪个流是最重要的,有一些依赖参数,这样一个流可以依赖另一个流。优先级别可以在运行时动态改变。
      • 优先级最高:主要的html
      • 优先级高:CSS
      • 优先级中:js
      • 优先级低:图片

    服务端推送(Server Push)

    • 服务器可以向客户端推送资源,不需要客户端明确地去请求。省去了客户端重复请求的步骤。
    • 这种服务端推送是基于客户端的请求响应来确定的
    • server推送能把客户端需要的资源随着index.html一起发过去。相当于在一个html文档内集合了所有的资源。
    • 服务端推送另一优势:缓存,在遵循同源的情况下,不同页面之间可以共享缓存资源成为可能。
    • 当服务端需要主动推送某个资源时,便会发送一个 Frame Type 为 PUSH_PROMISE 的 Frame,里面带了 PUSH 需要新建的 Stream ID。意思是告诉客户端:接下来我要用这个 ID 向你发送东西,客户端准备好接着。客户端解析 Frame 时,发现它是一个 PUSH_PROMISE 类型,便会准备接收服务端要推送的流。

    img

    HTTP2.0性能瓶颈

    • 现在所有的压力集中在底层的一个TCP连接上,TCP很可能就是下一个性能瓶颈

    参考

  • 相关阅读:
    Java基础语法
    Struts2--带参数的结果集
    Struts2--Dynamic Result动态结果集
    Struts2--Global Result全局结果集
    Struts2--Result类型
    Struts2--默认Action
    Struts2--模块包含
    Struts2--访问web元素
    puppeteer 填充基础表单
    animejs 动画库
  • 原文地址:https://www.cnblogs.com/xuwanwei/p/14506962.html
Copyright © 2011-2022 走看看