前言:
朋友那边邀请我去做个技术分享,本来我是打算讲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
部分截图:
关键字:
// 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很感兴趣,讨论是很热烈。结尾时,他们问的问题我都回答出来了,没有丢脸。😅