一文看懂静态资源服务沉浮及其在携程的演进( 五 )


Ansible 是一个基于 SSH 协议的中心化运维工具 , 只要拥有SSH 访问权限 , 就可以通过脚本(Playbook)安排远端服务器完成任何算力能及的工作 , 而不需要在服务器上额外安装任何客户端或代理软件 。我个人非常喜爱这款轻量化的DevOps工具 , 只是相见恨晚 。后来源站应用标准化 + 容器化了 , DockerContainer 取代了 Virtual machine , 而 DockerFile 取代了 Playbook , 真真是长江后浪推前浪 , 不许英雄见白头啊 。
四、分久必合系统迁移这件事 , 说破了天也只是清理技术债 。没有哪个正常人类能够分辨水电和火电对于 HiFi 音质的影响 , 同理 , 后台架构和运维技术的改变也无法直接提升用户体验 。因此 , 在消化沉疴的同时 , 我们也力争有所输出 。静态资源在线合并功能(res-concat) , 就是与系统迁移同时期的产物 。
分久必合 , 合久必分 。还是要从“分”说起 。
HTTP Archive 的抽样报告显示 , 今天(2020年4月)一个网页平均消耗的流量高达2MB , 这在使用电话线上网的年代 , 简直无法想象:56kbit/s的“猫”(MODEM)就算拿出吃奶的劲儿 , 也得花上5分钟才能把这么多内容扒拉下来 , 搁现在短视频都已经刷完一打了 。

一文看懂静态资源服务沉浮及其在携程的演进

文章插图
 
图片截取自 httparchive.org
带宽如此宝贵 , 发布在万维网上的每个字节都值得掂量 。图片是首当其冲的节流对象 。在次世代的 Web 论坛中 , 时常能看到标题中带有「大图杀猫」警示字样的帖子 , 表示帖子里含有字节可观的图片 , 爱惜流量者应审慎点击 。那种欲拒还迎的气质 , 和时下公众号里出没的「长文慎入」如出一辙 。
使用模拟信号的电话线路带宽有限 , 丢包率更是高得可怕 。访问大码资源不仅极度考验用户的耐心 , 中途失败、前功尽弃的可能性也不容忽视 。所以严肃的商业网站在使用大幅背景图片时 , 会选择渐进式 JPEG 格式 , 或者将图片切分后装进表格布局 , 有点像当今微博或票圈的图片九宫格 。甚至在2014年 , 我们还研究过如何在浏览器端通过精益控制渐进格式图片的下载 , 来提升移动设备跨网络条件(2G / 3G / WIFI)下的访问体验 。毕竟 , 过独木桥的时候 , 小步快走是一种理性的姿态 。
控制资源单体尺寸的考虑 , 对于文本格式的 JS / CSS 同样适用 。将代码按照功能拆分成若干文件 , 有利于资源下载成功 , 有利于资源重复使用 , 有利于防止 CPU 在等待资源下载期间闲得发慌……就没什么坏处吗?当然有 。
内容总量不变 , 文件粒度越小 , 请求次数越多 。每一次 HTTP 请求背后 , 都有附带的流量成本和时间成本 。仅仅是请求首部中一条用来表明浏览器身份的 User-Agent 字段 , 往往就有一百多字节 , 请求和响应首部加起来超过 1KB 是稀松平常的事 。而且 , 在 HTTP/2 之前 , HTTP 首部是不支持压缩的 。(User-Agent 字段为什么这么长?它们你中有我 , 我中有你 , 根本就是一个无间道的故事 。)
一文看懂静态资源服务沉浮及其在携程的演进

文章插图
 
一个 HTTP 请求的时间瀑布图(图片截取自 Chrome 开发者工具)
重新建立 TCP 连接也是颇费周折的 , 如果是HTTPS 请求就更麻烦一些 。启用长连接会有帮助吗?会 , 所以 HTTP/1.1 已经默认这么做了 。但是 , 长连接中的序列化请求会遭遇队首阻塞(HOL blocking) , 即使是管线化(pipeline)请求也要遵循先入先出的原则 , 不能从根本上解决这个问题 。
一个长连接不够 , 多建几个可不可以?作为 HTTP/1.1 规范文本的 RFC 2068 和 RFC 2616 均规定:单个客户端与任意服务器或代理之间的并发连接不得超过2个 。不过浏览器厂商们对此不以为然 , 争相放宽限制 , 以免在“全世界最快浏览器”的竞争中落入下风 。允许浏览器最多和同一服务端同时建立6个长连接 , 几乎成了事实上的标准 。因此后来连 W3C 也不再坚持原来的说法 , 在RFC7230 中只是含糊其词地表示 , “客户端应当(ought to)限制与特定服务器之间的并发连接” 。同样是“应当” , ought to 和 SHOULD 可不止是大小写的区别 。然而并发连接数终归没有彻底失控 , 惟恐触发 DDoS 攻击防御机制是一方面 , 另一方面也说明长连接并非是万灵药 。


推荐阅读