淘宝前台系统的优化历程
2009年,系统拆分,静态文件合并,前端页面异步化和JSON化。
2010年,去DB依赖,引入缓存,提升单机QPS,关注用户体验。
2011年,优化进入深水区Velocity,BigPipe。
2012年,静态化改造。
2013年,统一Cache,CDN化,网络协议。
高访问系统的静态改造
什么是静态化系统?
几个特征:
- 一个页面对应URL通常固定。
- 在页面中不能包含与浏览者相关的因素,这里所说的“不能包含”不包括JS动态生成的部分,也就是在页面中HTML代码不能明显地含有与浏览器相关的DOM。
- 在页面中不包含时间因素。页面同样不能含有与时间(而是服务端输出的时间)相关的因素,页面中的DOM不随时间变化而变化。
- 页面中不包含地域信息。
- 不能包含Cookie等私有数据。
为什么要进行静态化架构设计?
系统经过多次优化升级,包括系统架构的升级,系统本身的模块优化,代码优化和增加各种缓存等这些优化,我们的优化层次都是在java系统中做改进的。在这种情况下压测我们的java系统,性能依旧不能满足我们的期望,我们的目标是再上一个数量级。java本身遇到了瓶颈,自然就想到了静态化这种架构,让请求尽量不进过java。
那么系统静态化为何能做java系统做不到的高性能呢?静态化有如下优点:
- 改变了缓存方式。直接缓存http连接而不是仅仅缓存数据,web代理服务器根据请求url直接取出对应的http相应头和响应体直接返回,这个响应连http协议都不用重新组装,同样http请求头也不一定需要解析,所以做到了获取数据最快。
- 改变了缓存的地方。不是在java层面做缓存而是直接在web服务器层上做,所以屏蔽了java层面的一些弱点,而web服务器(如nignx,apache,varnish)都擅长处理大并发的静态文件请求。
如何改造动态系统?
- URL唯一化
- 分离与浏览者相关的因素。
- 分离时间因素。
- 异地化地域因素。
- 去掉Cookie。
- 动态内容结构化。(ESI和CSI)
ps:
ESI(Edge Side Includes)-即在web代理服务器做动态内容请求,并将请求插入到静态页面中,当用户拿到页面时已经是一个完整的页面了。这种方式对服务端性能有些影响(同步集中请求),对对用户体验较好。
CSI(Client Side Include)-这种方式就是发起一个异步js请求单独向服务端获取动态内容。对服务端性能影响小,但是用户端页面有些延时。
如何选择静态化方案的设计?
nignx+cache(静态文件)+java 结构虚拟机单机部署
nignx+cache(静态文件)+java 结构实体机(增大cache内存,增大缓存命中率-采用一致性hash分组)单机部署
统一cache层+java(把nignx和cache层统一管理和运维)
缓存失效问题?
被动失效:采用设置cache时间长度自动失效,也可以开发一个cache管理界面手工失效某些cache。
主动失效:
- cache失效中心监控数据库表变化发送purge失效请求
- 装修时间戳比较失效装修内容
- java系统发布清空cache
- vm模板发布清空cache
其中失效中心承担了主要的失效功能,失效中心的逻辑图如下: