当我们在谈论HTTP队头阻塞时,我们在谈论什么?

近来访问网站,明显感觉支持HTTP/2的网站越来越多了,对行业来说是个好趋势。HTTP/2的RFC虽然写的很厚,但是总结起来就做了以下几件事:

  1. 通过TCP多路复用降低延迟;
  2. 单个TCP连接上允许乱序request-response,解决队头堵塞问题;
  3. 实现层面上,大部分浏览器要求HTTP/2必须开启TLS,一定程度上解决数据安全问题。

其中,队头阻塞问题真的被解决了吗?

HTTP/1.1为什么会队头阻塞?

HTTP/1.1通过pipelining管道技术实现一次性发送多个请求,以期提高吞吐和性能,如上图中的序列2。然而,这种技术在接收响应时,要求必须按照发送请求的顺序返回。如果,第一个请求被堵塞了,则后面的请求即使处理完毕了,也需要等待,如上图中的序列3。

那么,HTTP/2是怎么解决这个问题的呢?那就是数据分帧:多个请求复用一个TCP连接,然后每个request-response都被拆分为若干个frame发送,这样即使一个请求被阻塞了,也不会影响其他请求,如上图序列4所示。问题完美解决了?准确说,只解决了一部分。

如果队头阻塞的粒度是http request这个级别,那么HTTP/2 over TCP的确解决了HTTP/1.1中的问题。但是,HTTP/2目前实现层面上都是基于TCP(没错,HTTP从来没有说过必须通过TCP实现,你可以用它其他传输协议实现哟),因此HTTP/2并没有解决数据传输层的对头(包)阻塞问题。

如上图所示,当第一个数据包发生丢包的时候,TCP协议会发生阻塞会进行数据重传。虽然TCP有快速重传等机制来缓解这个问题,但是只能是缓解。无法完全避免。

如何解决传输层的队头阻塞问题?

应用层无法解决传输层的问题。因此要完全解决队头阻塞问题,需要重新设计和实现传输层。目前而言,真正落地在应用的只看到Google的QUIC. 它的原理简单讲,就是使用UDP实现了一个可靠的多路复用传输层。我们知道UDP是面向数据报文的,数据包之间没有阻塞约束,QUIC就是充分利用这个特性解决传输层的队头阻塞问题的。当然,QUIC的协议实现有非常多的细节,而这方面Google确实做得非常好,如果你想进一步了解,可以关注他们的开源实现

需要说明的是,当前的QUIC实现使用HPACK压缩http header, 受限于当前HPACK算法实现,在QUIC中的header帧也是受队头阻塞的。但是粒度已经降低到了帧这个级别,并且仅会在header帧中出现。实际使用中,出现的概率已经非常低了。

小结

  1. HTTP/2 over TCP(我们接触最多的HTTP/2)解决了http request级别的队头阻塞问题
  2. HTTP/2 over QUIC解决了传输层的队头阻塞问题(除去header frame),是我们理解的真正解决了该问题。

APP上传文件到云端的正确姿势:据说值三万美金

APP上传文件到云端的正确姿势

近几年云存储和CDN的普及给多媒体文件存储和分发带来了诸多便利。如今要上线一个基础功能视频、图片网站,使用CDN厂商提供的服务,转码、存储、分发,甚至简单的访问控制都一站式搞定。想想以前个人站长时代,需要自己加硬盘、买带宽,自己使用ImageMagick和ffmpeg转码?‍♀️,真是酸爽。

云储存带来便利的同时,有很多安全问题往往容易被忽视。前段无人机独角兽大疆创新DJI爆出SSL 密钥和AWS key泄露问题,这使得黑客可以直接访问用户的私有视频内容。更有意思的是,泄露的原因居然是因为大疆把key放在了github上的开源项目的固件firmware中,而且已经这么放了4年,四年……?。这件事有意思的是,发现该密钥的哥们是一名叫做KF的白客,并把这个问题报告给了大疆,准备领取$30000的奖励,还预定了Tesla Model 3, 结果大疆法务把这花小钱就能解决的大事给谈炸了,KF的特斯拉没有了,但是大疆损失的可就不止这点小钱了。喜欢看故事的同学可以移步大疆 VS “白帽子”,到底谁威胁了谁?

如今移动互联网的天下,几乎每个APP都会上传文件到云端。这里,我们谈一下上传文件到云端的错误姿势背后的原因,以及正确姿势是什么样的。

错误的姿势

将云端的key保存在APP,然后APP直接调用接口上传文件。

很惊讶?我们的独角兽公司大疆同学就是这么干的呀。其实,不需要嘲讽大疆,你可以问一下你身边的互联网公司工作的同学,结果会让你更惊讶。

就我了解的情况,走上这条不归路有这几类原因:

  1. 创业公司野蛮生长的技术债。
  2. 部门墙的原因,有些公司的云端账号可能掌握在客户端开发小组的手里,而客户端同学对于服务器端的安全问题相对欠缺知识背景和敏感度。
  3. 程序员偷懒,不走云端标准交互流程,并且有严重的侥幸心理。

正确的姿势

正确的姿势其实也是一句话:

密钥保存在服务器,客户端每次向服务器申请一个一次性的临时token或signature,然后上传文件。

据我们的使用情况看,国内的CDN厂商都支持这种授权三方上传方式。比如又拍云的认证授权,阿里云OSS的授权给第三方上传

当然,实际的系统不可能这么简单。下面以我们前端时间设计和实施的上传流程为例,介绍我们在设计文件上传时的考量因素:

名词解释:cds, content delivery service, 这是上述流程中唯一自己开发的服务,感谢CDN的普及?

  1. 根据我们以往的客户端文件上传监控,客户端上传文件第一次尝试的失败率约为4%(这其实是一个比较可怕的数字,同时你也可以感受一下4G网络的复杂性)。因此,客户端申请上传签名时,可以指定多种类型。在我们的系统中,我们实际使用了两个CDN厂商承载上传请求:阿里OSS和云拍云。默认通过阿里OSS上传,又拍云作为灾备上传。
  2. 为了能达到高于CDN厂商之上的可用性,我们使用了两家CDN厂商(又拍云和七牛)进行内容分发。访问每一个文件的完整url地址是可配置的,因此我们可以在任一CDN出现问题的时候,在后台切换CDN。
  3. 可能有同学发现了我们使用了不太主流的又拍云。没有什么特殊原因,只是因为给的价格折扣比其他两家要低。
  4. 所有的云端数据都保存在阿里OSS,主要是基于阿里OSS可用性是跨可用区的。另一方面,这也实现了云端储存与内容分发的剥离。这意味着我们可以无痛的更换又拍云或者七牛云。
  5. 客户端上传文件成功以后,cds会收到一个回调通知,这里我们做了文件内容的合规检查和内容审计。当然,你可以在这里做一些数据挖掘的事情。

小结

他山之石,可以攻玉。据说,大疆犯错的程序员已经被劝(开)退(除)了。如果你所在的公司还存在类似的问题,赶紧行动起来吧。

Yet Another GeoIP Alfred Workflow

Yet Another GeoIP Alfred Workflow

在浏览网站以及在选线路的时候,经常会习惯性的查看一下对方的IP及地理位置信息. 师兄的 ip.cn 以及 ipip.net 都是不错的选择。但无奈自己是小帽子 Alfred 控,本着少做体力活的原则,写了一个 Workflow.

ip me 查看本地的外网ip及位置信息

ip domain 查看域名ip及位置信息

ip url 查看url中域名ip及位置信息

如果觉得你也有这样需求,可以在这里下载,enjoy!

References

  • http://www.deanishe.net/alfred-workflow