技术分享之http2和quic的那些事儿

前言:

朋友那边邀请我去做个技术分享,本来我是打算讲service mesh,但据说上次他们在韩国的时候,就找了一堆人做service mesh的分享。可以说微服务这个话题,他们算是听腻味了 😅 。 正好我最近读完了http的rfc文档,就借此机会分享了下我对http的理解。

事后,我跟他们聊了不少微服务的技术相关问题,惊讶的发现他们还是没有理解透service mesh的精髓。

该文章后续仍在不断的更新修改中, 请移步到原文地址 http://xiaorui.cc/?p=6117

内容:

关于http2和quic的问题,大家可以看ppt里的内容,为了避免再写文章描述ppt里的内容,所以在写ppt的时候,就尽可能多画图多写描述,尽量让大家好理解。如果有不理解,可以问我。

其实,还是看http rfc文档靠谱,只是官方的文档说的太生涩,没有详细的场景描述。另外我在github里附带了golang quic和golang http2的客户端,服务端的完整实例代码,供大家参考测试。

ppt已经转成pdf扔到github了,有兴趣的可以瞅瞅,另外望大家在github上点个star。 😁

github pdf: https://github.com/rfyiamcool/share_ppt
pdf 下载:  http://xiaorui.cc/static/http2quic.pdf

部分截图:

http 1.1 缺点
http 1.1 缺点
http1 流处理
http 1.1 pipeline
http1.1 优化
spdy
http 1.1 vs http 2.0 对比
http 1.1 http2.0 性能对比
http1.1 http 2.0 性能对比
http2 优点
http2 二进制
http2 多路复用
推送
frame type 类型
http2 缺点
tcp 阻塞 队首阻塞
http2在丢包弱网络下的测试
quic 队首阻塞
quic rtt
quic 可靠性
quic 拥塞窗口
quic 支持情况
quic 特性
http3

关键字:

// xiaorui.cc

http2和quic那些事儿
 xiaorui.cc
 menu
 http 1.0 vs 1.1
 http 2.0
 quic
 http1.0 vs http1.1
 http 1.1
 http 1.0
 古董 …
 持久化连接
 缓存
 accept-range
 更多header语义
 http 1.1 的缺点
 Head-of-Line Blocking (No Pipelining)
 一个连接同一时间只能处理一个请求
 如果当前请求阻塞,那么该连接就无法
 复用
 http 1.1 定义的pipeline, 浏览器和开发
 者都不友好
 http 1.1 流处理
 client
 server
 client
 polling req
 server
 stream req
 waiting
 …
 polling req
 waiting
 …
 http long poll
 http long streaming
 独享连接 !!!
 waiting
 …
 http 1.1 pipeline
 client
 server
 未完全解决head of line blocking
 fifo原则, 需要等待最后的响应
 no pipeline
 client
 server
 多数http proxy不支持
 多数浏览器默认关闭 h1.1 pipeline
 Google Report
 pipeline
 https://www.chromium.org/developers/design-documents/network-stack/http-pipelining
 优化时延
 在浏览器多开连接,提高吞吐? chrome的连接数限制在6个
 资源合并
 时延
 吞吐
 精灵图
 多域名拆分
 压缩数据 (去除无用字符,gzip压缩)
 cookie free
 …
 短暂的spdy
 解决了http1.1的线头阻塞的问题 !!!
 HTTP
 SPDY
 SSL
 TCP
 功能
 多路复用
 优先级
 header压缩
 推送
 …
 短暂的spdy
 spdy vs http2
 header压缩算法不同
 完善控制协议
 2012年spdy出世
 支持明文HTTP传输
 2015年
 nginx移除spdy⽀持
 2015年http2出世
 …
 2016年
 chrome移除spdy⽀持
 http1.1 vs http2.0
 时延 !
 等一个是等, 多个一起等也是等 !
 http 1.1
 N个排队请求 >≈ N x latency
 http 2.0
 N个并发请求 >≈ N x latency
 http 1.1 vs 2.0
 http 2.0 优点
 请求/返回多路复用
 header压缩
 流控
 优先级
 服务端推送
 …
 概念
 stream
 一个完整的请求和响应的字节流
 message
 一个完整的http请求或响应,由一个
 或多个帧组成。
 frame
 通信的最小单位, 每个帧都包含帧
 头,可标识出当前帧所属的数据流。
 二进制分帧层
 多路复用
 并行交错地发送多个请求,请求之间互不影响。
 并行交错地发送多个响应,响应之间互不干扰。
 使用一个连接并行发送多个请求和响应。
 多路复用
 流量控制
 只能针对data frame帧
 初始化大小为 65535 字节 (2^16 - 1)
 可以针对连接限制 (stream id = 0)
 也可针对流限制 (stream id > 0)
 Data Frame大小为16K字节
 均衡分配可用的网络资源,尽可能让所有流拿到调度
 头部压缩
 通过rfc商定静态和动态表的扩展, header通过传递索引号节省空间
 使用Huffman进行编码压缩
 Hpack static
 含有61个映射
 也可对key单独映射
 http://http2.github.io/http2-spec/compression.html#static.table.definition
 wirshark hpack
 server push
 page.html
 page.html
 style.css
 style.css
 main.js
 push
 push
 main.js
 当服务端需要主动推送某个资源时,便会发送一个 Frame Type 为
 PUSH_PROMISE 的 Frame,里面带了 PUSH 需要新建的 Stream ID。
 客户端接收该 Stream ID的数据就可以了
 Server
 server push
 frame
 Length ( payload size )
 Length (24)
 Flags (8)
 R (1)
 Type (8)
 Type (类型)
 Flags (状态)
 R (保留)
 Stream identifier (31)
 Frame Payload (0 …)
 Stream Identifier
 Frame Payload
 frame types
 Header
 PUSH_PROMISE
 推送
 Data
 PRIORITY
 优先级
 RST_STREAM
 停⽌止 (由于错误)
 SETTINGS
 连接级参数
 PING
 GOAWAY
 停⽌止
 WINDOW_UPDATE
 流量量控制
 CONTINUATION
 扩展header数据块
 header frame
 Pad length
 Pad length (8)
 E (1)
 E 依赖排他
 Stream dep (31)
 weight (8)
 Header Block Fragment
 Stream dep
 weight 优先级 1-256
 Header Block Fragment 数据
 Padding 填充字节
 data frame
 pad length
 Pad length (8)
 data (*)
 Pading (*)
 data
 padding
 flags
 END_STREAM
 END_HEADERS
 PRIORITY
 …
 http 2.0 连接过程
 客户端用http1.1发起升级协议请求
 Upgrade: h2c
 HTTP2-Settings: 
 服务端使用http1.1返回 101 Switching Protocols
 服务端使用http2.0发送SETTINGS frame连接序言
 (preface)
 客户端也必须回应一个包含SETTINGS帧的连接序言
 协议解析
 END_STREAM=false
 END_STREAM=false
 END_STREAM=true
 END_HEADER=true
 data frame
 data frame
 header frame
 END_HEADER=true
 stream
 END_STREAM=true
 read data length in last stream
 how to test
 wireshark
 nghttp2
 nghttp -nv https://nghttp2.org
 http2 vs http1.1 效果
 https://http2.golang.org/gophertiles
 https://http2.akamai.com/demo
 http2的缺点 ?
 TCP三次握⼿
 TCP 拥塞处理
 Tcp fast open ?
 慢启动
   linux kernel 3.6 
 拥塞避免
 TLS的交互
 拥塞发生
 Tls 1.3 = 0 RTT
 TCP慢启动
 TCP队⾸阻塞
 这尼玛是TCP的缺点吧 …
 快重传
 慢启动
 快速恢复
 tcp hol Blocking
 stream 1
 http client
 stream 2
 stream 3
 server
 head of line blocking
 当某个tcp packet丢包, 触发重传定时器, 继而触发“拥塞发生”
 其拥塞窗口降为1, 对丢包进行重传, 未收到ack之前其他包阻塞 !
 how to do ?
 http2 多连接
 quic
 Akamai CDN report
 在频繁丢包的网络环境下, http2比http1的多连接更低效.
 http2 弱⽹络测试
 Charles
 Fiddler
 Quic
 HOL blocking
 HTTP1.1
 HTTP2
 HTTP over Quic
 TLS
 TLS
 QUIC
 TCP
 TCP
 UDP
 HOL blocking
 Quic
 HTTP2
 HTTP over Quic
 TLS
 QUIC
 TCP
 UDP
 IP
 quic over udp
 测试点
 TCP
 UDP
 Quic
 可靠性
 可靠
 不可靠
 可靠
 连接性
 面向连接
 无连接
 无连接
 流量控制
 optimize hol blocking ?
 UDP
 UDP
 UDP
 面向数据报文
 数据包之间没有阻塞约束
 丢包只会影响对应的stream
 前向纠错减少了重传的可能
 quic 0 Rtt
 client
 0 RTT
 使用UDP规避三次握手
 使用DH加密来规避TLS交互
 首包就可发送数据
 server
 tcp
 client
 quic
 tls
 ok
 client
 后面只要缓存不失效, 重连无需TLS交互 !
 server config
 ok
 tls
 quic tls 1.3 (1 rtt)
 http2 tls 1.2 (3 rtt)
 一次Server Config的缓存,
 server
 server
 ok
 quic重连后 0 rtt !!!
 quic 可靠性
 手段
 当发生丢包
 单调递增seq
 尝试使用前向纠错来修复
 前向冗余纠错 (异或)
 不能fec, 则失败重传
 失败重传
 发送数据A和B, 增加发送一个数据C等于A和B的异或。
 接收方接到这3个包的任意2个包,异或一下就可以得到第3个包。
 quic 拥塞窗⼜
 quic 拥塞窗口
 实现了tcp的Cubic和NewReno算法
 默认采用Cubic
 nack机制,由接收端告知哪几个包丢失
 Tail Loss Probes更及时的重传
 为毛还需要拥塞窗口算法呀?
 网络质量的探测, 避免流量浪费
 quic ⽀持状况
 运营商
 udp 降级
 udp qos
 chrome支持
 TLS
 Quic
 nginx tcp 443
 server
 caddy tcp 443
 nginx暂不支持
 caddy proxy
 nginx返回支持quic
 add_header alt-svc 'quic=":443"; ma=2592000; v=“39"';
 caddy作为quic代理
 quic 其他
 quic 连接性
 使用connection id来识别重新连接的请求
 quic 流量控制
 可以针对连接控制,也可以对具体的stream id进行控制
 万众期待的http3
 HTTP2
 HTTP3
 TLS 1.3
 TLS 1.2
 QUIC
 udp control
 TCP
 UDP
 IP
 google spdy
 http2
 google quic
 http3
 Q&A
 -

总结:

这次的技术分享会很是热闹,大家对http2 quic很感兴趣,讨论是很热烈。结尾时,他们问的问题我都回答出来了,没有丢脸。😅


对Golang感兴趣的朋友可以加群: 278517979 !!!
另外如果大家觉得文章对你有些作用! 如果想赏钱,可以用微信扫描下面的二维码, 感谢!
另外再次标注博客原地址  xiaorui.cc