使用HTTP/2.0解决浏览器限制同源HTTP/1.x连接并发个数的问题
近年来,浏览器正在逐渐减少对Flash播放器的支持,Adobe于2017年宣布将于2020年底停止对Flash播放器的支持,Google随即宣布跟进: saying goodbye flash chrome 。最新发布的Chrome 76默认禁止使用Flash播放器。
到目前为止,除了苹果的Safari浏览器之外,主流的浏览器几乎都已经支持 Media Source Extensions ,通过该技术,浏览器可以通过<video>标签播放常见的媒体格式,如mp4,fmp4,webm等。
在此过程中,出现了 flv.js 等不依赖Flash的浏览器播放器,它的工作原理是将浏览器接收到的flv tags转换成fmp4片段,然后喂给<video>标签来实现解码播放,从而摆脱了对Flash播放器的依赖。到这儿似乎一切都很完美,然后有人发现了问题,详情见
由于历史的原因,浏览器对同源HTTP/1.x连接的并发个数有限制,典型值是6,测试表明Chrome和Firefox都是这个值。要解决这个问题,常见的方法有:
1.域名分片(Domain Sharding),后端的服务器有可能是同一个服务器。
2.使用WebSocket协议,主流的浏览器对WebSocket连接并发数量的限制都远超6个。
3.使用 HTTP/2.0 ,理论上HTTP/2.0协议支持在同一个TCP连接上发送无限个HTTP请求,且这些请求的生命期可以重叠。
提到HTTP/2.0,需要先了解SPDY,详情见
它是Google于2012年提出的一个协议,具有如下特性:
1.在一个TCP连接上发送多个HTTP请求,且这些HTTP请求的生命期可以重叠。
2.请求具有优先级,可以优先发送高优先级的数据。
3.对HTTP头进行压缩,减少了带宽占用量。
4.全双工通信,允许服务器向客户端主动推送信息。
IETF于2015年接受SPDY草案,并在SPDY基础上进行了标准化工作,发布了HTTP/2.0协议,Google在2016年宣布不再支持SPDY,转而使用HTTP/2.0。
区别于HTTP/1.x只能在一个TCP连接上发送一个HTTP请求(HTTP/1.1支持pipeline,可以发送多个HTTP请求,但是这些请求的生命期不能重叠,即只能串行执行,需要区别客户端和服务器角色的本质,且一般服务器会限制pipeline的HTTP请求个数),HTTP/2.0理论上可以在一个TCP连接上发送无数个HTTP请求,而这些HTTP请求在浏览器看来,只是一个连接,所以避免了同源并发个数限制的问题。
虽然HTTP/2.0的RFC没有要求对HTTP/2.0请求强制加密,但是目前主流的浏览器和服务器的实现几乎都要求对HTTP/2.0强制加密。Firefox从版本36.0.0开始支持HTTP/2.0;由于浏览器默认发送的请求是HTTP/1.1,如果要升级成HTTP/2.0,需要加密软件支持应用层协议协商(ALPN),OpenSSL从版本1.0.2开始支持HTTP/2.0(CentOS 7.x系统自带的OpenSSL支持);Nginx从版本1.9.5开始支持HTTP/2.0。
本文测试环境是:浏览器Firefox 52.8.0;flv.js 1.5.0;服务器操作系统CentOS 7.3,加密软件OpenSSL 1.0.2k(操作系统自带);服务器Nginx 1.12.2,完全满足上述的要求。使用的直播服务器是我开发的nginx-http-live-module,推流软件是 srs-bench ,测试的录屏截图如下所示:
可以看出,使用HTTP/2.0后,浏览器可以打开9个播放请求,其实测试打开12个播放请求也没有问题,但是由于测试时笔记本的CPU使用率过高,所以没有测试更多的播放请求,能支持的播放请求最大数量未知。
注:nginx-http-live-module是在 nginx-http-flv-modu le基础上开发的商用软件,后续我会将nginx-http-live-module的一些功能添加到nginx-http-flv-module中。
本文从使用HTTP协议的视频播放角度验证了HTTP/2.0解决浏览器限制HTTP/1.x同源连接并发个数的问题,实际上,只要浏览器使用HTTP/1.x与服务器通信,就会有上述的限制问题,浏览器并不关心HTTP/1.x协议传输的是什么。