了解淘宝最基础知识,淘宝退货必须要写淘宝账号吗( 六 )


2、PHP 到 Node 的变迁
淘宝首页日均请求的这个量级 , 不可能是十几二十台台服务器抗得住的 , 支撑它必须有一个服务集群 。
每一个 CDN 节点上都具备 PHP 渲染的能力,当页面发布时,我们把该页面所有的模块和数据同步到全部 CDN 节点上,基本模式大概就是如此了 。看起来还挺不错,但是经过一段时间的运维 , 很多安全、性能问题都慢慢浮现出来了:
性能问题 。每个 PHP 页面包含多个子模块,而子模块也有可能引用了其他的子模块,PHP 的 include 操作是存在消耗的,每一次引用都是一次磁盘 IO,一个渲染节点上跑了成千上万个类似淘宝首页的 PHP 页面,并发一高其效率可想而知 。
推送机制问题 。文件同步是一种比较恶心的机制 。首先,时间上没法控制,一个文件同步到所有的节点,快则几秒钟,慢的话耗时会超过一两分钟;并且同步过程还有可能失败,健康检测的成本也是相当高的 。发布比较紧凑时,需要同步的文件也很多,很容易造成队列堆积,加剧同步差的体验 。
实时性强需求问题 。文件在推送之前,还可能经过一些前置系统,发布链路越长,线上生效时间越慢,慢的时候大约五分钟才生效,这样的延时对于实时性要求很高(如秒杀)的需求来说是完全不能接受的 。
当然,还有很多其他问题,如运维成本增高、安全风险增高、PHP 资深人才储备不足等等 。所以 PHP 渲染容器的命运,就是,被干掉 。
服务集群为 Cache CDN,它只有静态文件处理能力,没有 PHP/Node 的渲染能力,所以处理效率高,性能也好,抗压能力相当强,并且扛不住的时候还可以花钱买服务,拓展 Cache 集群 。
用户访问时,Nginx 转到 Cache CDN,如果命中缓存则直接返回,没有命中便回源到源站服务器 。源站服务器是具备模块渲染能力的 Node 服务,它可以做很多事情:
· 控制 Cache 响应头,通过 max-age 和 s-maxage 控制页面在客户端的缓存时间以及在 Cache 上的缓存时间,这个缓存时间可以根据需求随时做调整,比如大促的时候调长一些;
· 控制内外网环境,和 AB 测试状态;
· 融合前端相关的工具链,比如检测、压缩、过滤等等 。
它的优势有很多 , 这里不一一列举了 。这个模式中还添加了一层容灾 , 源站服务器每隔一段时间将数据推送到于 Cache 同机房的备份服务器,一点源站挂了,还能够自动容灾到备份数据上 。
模式的变化不仅在运维上有了突破,CDN 被攻击时的安全风险也低了很多,同时也省却了 sync 所需的各种检测机制,每年节约成本也是百万以上,优势还是相当明显 。
3、Node,不一样的模式
上面 PHP 模块中,我们只说了 HTML 和数据部分,用心的读者应该已经发现,CSS 和 JS 这些静态资源都没提到,那页面是如何渲染的呢?
旧版 PHP 页面中,我们是直接引入了一个 CSS 和一个 JS,淘宝这边采用的是 git 版本迭代发布,这些静态资源都是直接放在一个 git 仓库中 。也就是这样:
每次发布完 git 文件,再修改 PHP 的.版本号,然后发布 PHP 代码 。当然,也做了相关的优化,比如发布 git 时自动更新版本号等 。
一个模块的 CSS/JS 和模板放在一起 , CSS/JS 与页面其他模块的静态资源是相互独立的,目的就是希望单个模块也能够完整的跑起来,更加利于模块的复用 。
而模块的挖坑,也从模板中独立了出来,采用 JSON Schema 的形式定义数据格式:
模块之间相互独立隔离,所以会存在一定程度的冗余,不过模块解偶带来的收益要比这点冗余要多得多 。事实上 , 我们是通过一个仓库去管理单个模块的 。页面的渲染就比较简单了,源站 Node 容器会将所有的 index.xtpl 合并成一个 page.xtpl,为减少页面请求,css 和 js 也会 combo 成一个文件 。