对于每天上亿流量,拥有上亿页面的大型电商网站来说,能够支撑高并发访问,同时能够秒级让最新模板生效的商品详情页系统的架构是如何设计的?接下来咱们就剖析一下这些电商网站的商品详情页的整体架构。 那就按照商品详情页的架构演化过程来进行一一的说明: 架构1.0:大概2012年的时候,某大型电商网站还在用spring mvc的模板渲染(freemarker等)方式,动态生成商品详情页面。某些数据也进行了缓存。随着流量的激增,性能逐渐出现了很大的问题。 架构2.0:niginx java的全量静态化页面方式: 也就是2013年的时候,此电商网站架构进行了升级,采用了前后台分离,前端资源动静分离。主要的设计思路是,在后台管理系统编辑完商品,进行审核后,上架商品的同时就把当前商品的静态页面自动生成到服务器端。(如果商品的数量比较多时,也可以采用mq的方式进行模板页面的生成)简单举个例子:商品的id是123456,那直接会生成一个123456.html在服务器上,当详情页面请求来的时候直接通过nignx访问123456.html,而无需再通过后台应用访问数据库加载数据了。 优点很明显,性能得到了很大的增加。对于一些中小型电商网站,已经满足了需求。但是对于大型电商网站,缺点也是有的,主要以下两点:1)如果页面规模很大,几亿级别,niginx的资源明显不够用。2)如果页面模板修改了,那所有的页面都得重新静态化一遍,那是不切实际的。 架构3.0:2014年采用了异步多级缓存架构 nginx本地化缓存 动态模板渲染的架构 主要思路是通过多级缓存来实现。首先大量请求来的时候,80%的请求通过nginx本地的缓存数据进行模板渲染后,直接返回了html。剩下的20%中的80%(16%)通过redis中的缓存数据进行模板渲染。最后4%的数据中大部分走缓存数据服务的本地缓存,只有很少量的请求会直接打到数据库。这样就大大提高了页面的性能,也减少了数据库的压力。当然这样的架构优点是明显的,缺点就是架构复杂,会涉及到很多复杂的问题,需要一一去想办法解决。说点题外话,世上任何东西都具有两面性,没有一个是只有优点没缺点的,做架构设计也是如此,得懂得有舍有得。 这个架构设计到几个主要的技术点: 1)nignx的本地缓存(HttpLuaModule模块的shared_dict)的使用和lua脚本的模板渲染。Lua中也有许多模板引擎,如目前的lua-resty-templat。 2)redis集群的使用。 3)nignx的缓存容量有限,要考虑多台nignx的路由策略。每台nginx不可能都放相同的商品模板,所以可以用商品的id进行hash路由。 4)毕竟缓存空间是有限的,所有的缓存(三级缓存)要考虑失效策略。比如LRU。 5)三级缓存随着缓存级别,容量是逐渐减少的,一级缓存(nignx缓存)容量最小也就200M左右,所以不可能上亿的商品页面都放到一级缓存,需要考虑一些什么样的商品数据存入一级缓存。比如秒杀的商品可以放入一级缓存。二级缓存的存放规则可以参考二八原则,也就是80%的请求只访问20%的商品。所以将热点商品数据存放如二级缓存即可。当然这个也不是固定不变的,假如当某个事件导致某个冷数据商品突然变成爆款,也是需要动态推送到一级缓存的。这个可以设定一个访问请求上限,达到上限后可以自动推送至一级缓存。 |
|