周六,参加完SD大会,Facebook的蒋博士被邀请到杭州的淘宝做一次技术分享。由于没有参加北京的velocity大会,上海的SD大会蒋博士的内容又由于时间问题被压缩的变形,所以周六无论如何都去听一次。原定10点开始的会议,9点50分诺大的淘宝培训室就没有座位了,后续不断地还有同学涌入,当然我看了一下,集团的每个子公司的人都有,各种岗位的人都有,其实今天的优化分享主要还是侧重于前端,而那么多人来听,我觉得和我来的出发点一样:“技术不分领域和语言,设计触类旁通”。
这里只是记录自己的一些学习理解和体会,其中的思考一些是自己看的清楚的,一些还是比较迷惑的,因为毕竟不是做前端的,欢迎讨论,具体的内容参看PPT:http://velocity.oreilly.com.cn/ppts/ChanghaoJiang.pdf。
网站的请求其实可以分割为多个步骤:网络传输消耗,服务端业务处理消耗,页面渲染消耗。(如果更细致,其实可以将网络传输消耗细分成DNS解析,连接建立及网络传输消耗)Facebook从局部和整体的角度考虑优化,提出了三个优化方式:Quickling,PageCache,BigPipe。每个优化都有适用的场景,所以每个技术优化点前面我先写一下场景。
Quickling优化场景:用户页面切换频繁。优化方式:通过ajax方式模拟页面内容切换。优点:降低传统页面切换对于资源载入和卸载在前面提到优化场景的损失,服务端对于可重用的内容不必再做重复渲染。缺点:页面复杂度增加,包括模拟传统页面的前进后退,爬虫对页面的信息获取,缓存资源必须在一定时间内批量释放。
思考:浏览器载入和卸载页面的消耗究竟在什么地方?编程复杂度的提高(模拟浏览器页面行为)和收益(特定场景,复用性)。因此这点对于网站来说最多也是部分页面的适用或者部分场景的适用,同时带来的维护成本有点高。当前很多场景开始使用Comet的模式(如果用ajax模式,那么就和Quickling一样),通常情况下,Comet用于单个页面的增量数据推送,不存在页面切换的那些复杂模拟问题。
PageCache优化场景:用户行为在多个热点页面中反复切换。优化方式:基于Quickling的流程,在客户端做数据缓存。优点:热点页面渲染快,服务端压力下降。缺点:数据即时性问题。(当前可以模拟单客户自己的操作行为,保证显示及时性,但是如果服务端状态变更,消息无法通知,页面数据较老)
思考:其实就是将可以缓存的数据尽量缓存,提高页面渲染速度,过去切割页面用ajax局部渲染,现在整体都用ajax,本来的局部渲染需要通过内部实现,但缓存最大的问题就是状态及时性,对于用户数据显示要求不高的可以用这种方式。(我的淘宝页面不可以用,及时性要求太强,虽然这是热点页面)。总体上来说还是多页面的Comet实现中缓存的一部分。
延伸:服务端管道化模式中,可以考虑部分管道结果缓存。简单来说原来一个请求一个事务,现在被切割成多个小任务通过事件驱动的方式或者简单的管道串联的方式执行后,可以将某一个环节的中间结果缓存,那么可以提高部分子任务的执行效率,在原来一条道走到黑的情况下做起来很复杂也很难看。
BigPipe优化场景:整体页面可以被切割(无强依赖),每个切割块之间可以并行被执行。优化方式:页面切割为多个Pagelet,交由Ajax框架调度并行或者串行执行请求(当前主要使用串行化,通过局部增量显示,提升用户体验)。优点:用户体验增强。
在开放平台服务请求中,我们的Pipe支持演进和BigPipe很类似,如下四图:
常规的web请求,容器负责业务线程的管理,业务请求直接在一个Service方法中完成。
还是常规的Web容器,但是将一个服务处理方法切割成多个Pipe,包含三个部分,准备,执行,释放,传统任务被分割,不同子任务资源生命周期缩短,资源利用率提升,如果采用Lazy解析数据流,则可以更好的提升上行带宽的利用率,另一方面可以缓存部分pipe的中间结果,提升部分pipe的处理性能。
采用支持异步化的容器,将业务线程池和容器线程池分开。容器线程池线程依然可以执行部分管道(消耗较低的管道),返回部分处理结果,业务线程池可以根据业务规则来区分对待不同的服务请求(在线程资源有限情况下优先保证重要服务被执行,Bigpipe也提到对于不同的pagelet的优先权重不同可以先后处理),最后返回剩余全部结果。
支持批量API请求和QL服务请求(前者是并行服务组合,后者是串行服务组合),容器执行公用的管道(消耗较低的管道),如果是QL call,则容器线程池顺序执行多个API call,最后返回结果。如果是batch call,则启动多个业务线程工作者,并行执行任务,随机返回部分结果。好处就是减少连接损耗,合并多个请求共同处理的消耗。
其实很多优化理念看似简单,但是作起来很多细节特别重要,就好比Quickling如何用ajax模拟前进后退历史,cache如何可选择的部分监听数据更新,bigpipe如何对不同客户端请求或者爬虫做支持。当然听完分享更需要注意的是自己的场景如何借鉴。