楚楚街是90后用户人群为主的特色移动电商,目前楚楚街只做移动端。平台目前用户数近亿规模,每日流量千万级别。
楚楚街早期以“9块9包邮”切入到电商业务,尽管目前平台已经转型为全品类高性价比的年轻用户喜欢的商品,但“9块9”早已深入人心。从2015年开始,楚楚街将9月9日定义为“楚楚节”,简称“99大促”。每年的9月9日,对于楚楚街来说,流量和业务成交都是与双十一比肩的。所以,对于楚楚街的技术人员来说,在双十一的准备方面有特殊之处:做好了99的考卷,双十一的压力就抗过了一大半。而这一份考卷不是模拟卷,而是真实的考试卷。
今年9月9日~11日,楚楚街的99大促顺利完成,抗住了峰值订单数为平时订单数100倍、流量峰值为平常峰值的50倍的压力。99大促的顺利进行不仅为双十一大促打下了良好的基础,也收获了很多宝贵的经验。大促的顺利进行离不开技术的支持,本文来介绍一下,楚楚街针对今年的两场大促,做了哪些技术上的优化升级。
楚楚街自营商城于2014年年底上线,上线后业务增长迅猛。与很多创业型公司面临的技术问题一样,早期的架构从底层数据到上层的web服务器全都耦合太强,所以从2015年7月开始,为了甩掉系统的历史包袱,开始做技术优化。而优化的核心就一个字——“拆”。
拆分我们主要按照如下几个阶段来做:
-
按照业务将落到服务器层的流量进行拆分
-
业务层代码的拆分
-
数据层的垂直拆分和服务化
第一阶段的拆分,
我们主要是梳理业务,将业务进行合理的划分
,将原始耦合在业务中的如短信、push、物流、ERP等抽象出平台级系统。其余核心业务如订单、商品、购物车、用户等系统,梳理好业务边界和接口,在最上层按照域名进行流量的切分,这样切分后,各个业务系统的边界清晰了,当大促等大流量活动期,也不会因为某一个业务流量过大引起整体业务雪崩,保证了部分业务可以正常运转。
第二阶段主要是做
代码拆分
,将过去耦合在一起的代码仓库根据第一阶段的拆分情况进行代码拆分,在拆分的基础上将冗余代码进行清理,可以有效提高系统的性能,增加了代码的可读和可维护性,各系统之间人员垂直,可以大大提升迭代能力。
第三阶段也是整个过程中最关键的阶段,那就是将业务下沉到服务,然后这个过程做
DB的垂直的拆分
。垂直拆分完成后,核心业务抽象成服务,将核心接口收拢,保证了有限的服务接口,提供了可分布扩展的性能,存储层可以根据服务接口解耦,并有效的保证了SQL等质量,保证了业务的稳定。
下面两图描述了我们拆前和拆后的一个架构对比。
图一:拆之前的架构
图二:拆后的架构
在拆的过程中抽象了很多基础系统:如分布式消息流、数据库中间层、基础业务服务化(用户服务、订单服务等)……
作为创业公司,“拆”的过程不允许耽误业务的发展。在业务发展中寻求技术优化,不耽误业务,与业务发展寻求一个契合点,需要有很强的业务理解力和技术把控力。目前,我们还走在整体服务化的路上。
多级缓存架构在大促这种大流量期间,针对于大量的“读”接口是意义巨大的,也是保证了大促期间业务稳定的重中之重,我们
以商品详情页为例
作一下介绍。
电商的流量大入口除了首页等导流页面外,商品详情页无疑是流量的集中点。而双十一、99等大促,详情页的访问量又达到历史之最。
详情页看似简单,但其有很多的业务逻辑:比如商品改价、库存变更、sku变更、评论评价等各类与数据强相关的业务逻辑。而详情页有一个非常大的特点,就是基本以读请求为主,因此,针对详情页这类的业务,我们创建多级缓存架构。
多级缓存架构根据业务流量的变化,是一个漏斗模型的系统架构,下层的流量越小,系统就越稳定,目前我们多级缓存架构主要是三层。
第一层是CDN,这一层主要缓存的是大促期间的主会场、分会场、秒杀商品的静态页、商品的富文本详情页、商品属性页等。这部分页面都是大促期间流量最大的,也是最要求速度和体验的,放到CDN,用户根据就近节点进行访问,大大加快了访问速度,并且减少了服务器层的压力。
第二层,我们用Nginx+Lua+OpenResty做了代理层缓存,这层缓存主要缓存住了提供给客户端的API接口的数据,这层cache根据商品的业务需要,会在活动规定时间内决定其cache有效性,一旦商品所在的活动失效,才会走到下一个层次——业务层;而99%以上的流量都在这一层给抗住了。
下图是本层的一个过程图。
第三层,我们在业务层添加了Memcached和Redis的Cache,这一层缓存了DB或者服务化接口拉取出来的数据,这层缓存的主要都是商品ID等纬度的业务数据,根据业务流转情况,保证这层的Cache数据都是实时的,确保了到DB层的量几乎很少。
最后流量才到数据库。数据库所起的作用是数据的持久化以及部分缓存失效的主动更新。根据这个架构,到达数据库的流量很少。
这套架构模型,让我们的详情页访问时间从早期的100ms左右,降到了20ms以内。同时单机能承载的详情页请求数量增加了100倍以上。
下图是此架构服务器部署的一个概述。
1. 流量预估和压测的意义
在每次有新系统上线,或者技术驱动的系统优化完成后,我们会进行系统压力测试。系统压力测试能非常清楚得知道:
对系统的压力有了预期,那么我们可以根据大促流量的情况,提前准备好机器。根据大促的流量如何,我们会对系统进行调整。
2. 如何进行流量预估
如何进行流量预估,流量预估其实是一个很难的问题。难点来自于以下2个问题:
针对第一个问题,我们会看总体运营数据和电商的行业总体情况来预估今年大促的用户量级。所以我们会抽取2015年大促的访问日志来做大规模用户行为分析,大致得出大促会场页、商品详情页、购物车、下单等的访问比例和峰值。
针对第二个问题,我们会提前跟业务团队同步大促要进行的活动内容,包括活动预热和大促当天。通过业务的理解来折算系统的峰值。
3. 如何压测
有了流量预估,就要对我们的性能进行压测。压测分为测试环境压测和线上生产环境的压测。我们更侧重于拥有流量链路的生产环境的压测。为什么流量链路的生产环境压测更为重要呢?因为业务其实一直是在变化的,生产环境的机器硬件环境也好、网络情况和整体业务链路都跟测试环境模拟出来的相差较大,当然压测出来的结果也是有所差异。
压测的方法,业内比较常见。我们采用了以下几个方法:
4. 总结
拿到压测结果,对于性能的短板,我们便开始进行性能改造提升。并且根据每一个服务的机器状况,在云端提前进行机器购买和刻录,为大促做好准备。
监控
楚楚街开发了一套自动化运维系统CMDB。CMDB实现了线上服务器的实时水位监控、业务服务监控、机器自动上下线、代码自动化部署等常见运维功能。根据机器、服务、业务的不同粒度,CMDB在监控和运维的功能描述如下:
在大促期间,运维同学根据业务线实时监控以及各类报警,能在第一时间发现有问题的业务、机器或者服务。根据不同问题的粒度,通过事前准备的预案,第一时间在CMDB上触发切换预案。