@
zhicheng 一,把文本协议换成二进制协议并声称减少了流量,并不算是一种进步。在流量宝贵的时期选用文本协议,是有所考量的。相反在这个时代换回二进制协议,不得不说其实是一种退步。
其实 HTTP/1 时代,传输的内容也基本都是二进制:图片等多媒体本身就是二进制; CSS 、 JavaScript 、 HTML 都会 gzip 成二进制。 HTTP/2 无非就是把请求头 / 响应头这些之前的纯文本部分也变成了二进制,方便做基于字典的压缩和增量传输。随着一个网站几十上百个资源请求,头部浪费的流量也很可观,进行压缩势在必行。
二,把传输层协议放到应用层协议中实现,也不是明智之举。
这个确实不靠谱,但也是无奈之举。 HTTP 的传输层 TCP 跟内核绑得太紧了。举个例子, TCP Fast Open 算是传输层的优化,但是有几个人会为了这个升级 linux 内核?而把本应该传输层所做的优化拿到应用层就会好很多, HTTP Server 大家升级得总要勤快一些吧。目前 Google 的 QUIC ( Quick UDP Internet Connections )已在自家服务放了 50% 量,未来有一天 TCP 会被 HTTP 给抛弃也说不定,而 QUIC 更是一个跨多层的产物。
三,有了 WebSocket 之后 ServerPush 并没有非常大的用处。
ServerPush 目前确实没有多大用,但跟 WebSocket 无关。 ServerPush 推送的是资源,必须遵循请求-响应的循环,只能借着对请求的响应推送, PUSH_PROMISE 帧必须在返回响应之前发送,服务器不能随意发起推送流。 ServerPush 目标是替代 HTTP/1 时期为了减少页面时延所普遍采用的资源内联( inline )的做法。至于 WebSocket 纯粹是依赖于 HTTP upgrade 的全新协议,目的是双向通讯。实测中它的连通性大概在 50% 左右,一般实战中需要部署 WSS 增加网络穿透能力,以及采用 SSE 、 Pulling 等降级方案。
另外,我补充一点: HTTP/2 的多路复用很有用。 HTTP/1 时期,一个 TCP 连接上同时只能传输一个 HTTP 请求 / 响应。为了增加并发,浏览器都会开启多个 TCP 连接并发获取资源。大部分网站还会对资源进行域名散列,来绕开浏览器对同一域名并发数的限制(实际上, HTTP/1.1 协议 RFC 2616 版中规定了同一域名最多只能有两个并发连接,但几乎没有浏览器按标准实现, RFC 7230 中直接去掉了这个限制)。本地 TCP 连接和本地端口也是一种资源,为了 WEB 性能,想尽办法建立更多的并发连接,是很霸道和不公平的做法。而 HTTP/2 的多路复用可以解决这个问题。
最后,尽管 HTTP/2 协议并没有规定 HTTP/2 一定要基于 TLS 实现,但是 Chrome 和 Firefox 都明确表示只支持 HTTP/2 Over TLS ,鉴于我国目前复杂的网络现状,如果能借 HTTP/2 推广 HTTPS 也是一件好事。