我这边是在京东某部门负责营销活动的开发,大家所知道的秒杀其实就是活动的一种,这些活动有个共同点,就是流量极大.首先每个商品你都要知道他是不是活动商品?属于什么活动商品?我有没有购买资格?活动的开团时间是什么?活动有哪些商品,每个商品的活动叠加结果是什么?还有许多活动有库存的概念,比如秒杀或者限量购,逻辑很复杂,这里里面有太多太多的细节,很多细节可能没法一一说清楚,这里总结些重要的秒杀的问题以及解决方案给大家,不扯虚的,全部是线上沉淀下来的纯干货
;
这里我以我做的一个最有意思的营销活动,先给大家介绍一下,不涉及技术,只是后面出案例会以此为案例而已,看技术可以跳过
我这个活动叫做《周期循环购
》,这个活动可以选择参与的商品,活动支持设置活动总的有效时间(比如2022-02-02 12:21~2033-12-02 13:22`),另外我们还支持让你选择周一到周日哪几天是开团日(比如周三,周五),每个开团日再进行设置哪几个时间段为开团时段(比如00:00~01:00,12:00:02:00),然后还支持设置商品在每个时段的库存是多少那么其实在这里看,团购的商品对于我来说就是一个产品的概念(SPU),而我的营销活动限制的库存才是真正的库存(SKU),另外这个又涉及到周期性库存的概念,每天每个时间段都有一个自己的独立库存,这比单一的商品库存要复杂许多许多。
正文:
一.明确团购秒杀为什么不好做?不好做,说道理是由于团购属于折扣商品,通常价格比较低,流量真的极大,并发访问下容易造成各种并发症,举几个例子如下:
服务器流量,负载极高,万一挂了就玩球了,这里可以指业务、中间件、数据库等服务器,比如数据库我们都知道抗压能力不咋地;流量不均匀,有些时候会有部分热门商品(比如首发的iphone)特别高频访问,把服务器资源全给占用了其他商品就被搁置排队了;逻辑复杂,下单和回滚或者取消订单要保证幂等,防止数据不一致以及超买超卖的可能,万一造成资损,大家都知道这个的严重性;二.如何解决秒杀可能带来的问题呢?我这里提出一些我在项目里使用的经验和技巧2.1.解决高流量问题首先流量过高,处理速度慢
是根本原因,因此我们最先解决这部分问题;
隔离
动态数据和静态数据,静态数据可以前置到用户端或者CDN里,比如商品图片这玩意,这样非必要的请求就可以拦截一部分了;后端数据加缓存
,让高性能的玩意直面高并发,比如我上面提到的营销活动,目前基本上做到了查询全部缓存化,所有查询全部走Redis缓存,大家都知道Redis的性能吧;限频
,比如限制用户对于同一商品详情页的刷新次数,大家是不是经常会在活动开始的时候疯狂刷新....到刷新频次的时候可以显示的提示,也可以默默的请求无效化,另外这种限制尽量前置化
,层层过滤
,另外涉及到数据校验的,如果大家的系统有多个层次(比如前端->api站点等->server),最好做好层层过滤,每个层次都将一部分数据拦截了,比如前端可以做限频,api站点层做风控,数据校验等等,这样最后有效请求就少了许多了;任务拆分
,尤其IO型,很多时候我们有些调用是不需要严格保障串行化的,比如获取商品详情接口,可能里面需要展示优惠券信息,以及该用户购买该商品的价格,库存余量,那么我们这里可能需要调用券服务A,计价服务B,库存服务C三个服务的接口,这三接口就没有先后顺序,并且都是比较耗时的服务,串行调用耗时A+B+C,比如0.4+0.5+0.5=1.4秒,那么我们多线程分发任务去调用的话,总耗时就是最长的服务时间即0.5秒。2.2.2 下单类请求(很多和上面一样的就不说了,比如层层过滤)削峰
,如果我们的流量极大,我们可以进行削峰限流,推荐大家采用异步下单的方式,安全可靠,所谓削峰限流我的理解是可以看做银行柜体,就算流量再大,你都要排队,能处理多少看银行的能力,我有一个银行就处理慢点,有十个银行就处理快点,没啥问题,大不了你就办不成功呗,当然这里注意防止丢单,可以采用分布式事务;
延缓请求
我们可以订阅系统负载,或者一些监控服务,在系统流量极大的时候,触发答题系统,在大家进行下单的时候进行答题,那么有的人答题快有的人答题慢,大家拼的就不全是手速了,还有脑速,哈哈,最主要的是把开团那一瞬间的流量均匀到答题的时间了,这点效果显著;
精准限流
,比如我们可以采用付定金预购的方式先把购买人群锁死,有几个好处:
限流
比如某接口服务压测的极限值是5W qps,我们就设置为4.5W为限流值,防止服务突破系统瓶颈,并做到既可以人工执行开关,也支持自动化保护的措施。这个一般公司的网关服务或者混沌工程里都会提供该服务;有一点需要注意的是,这里的限流其实也不只是保护自己的服务,其他作为被调用测的下游小伙伴的服务这里也起到的保护作用。
兜底
拒绝服务,根据系统资源的情况,为了防止系统产生不可控的情况,要做到考虑最坏的情况,那么最后一招就是直接拒绝服务了。
当系统负载达到一定阈值时,例如 CPU 使用率达到 90% 或者系统 load 值达到 2*CPU 核数时,系统直接拒绝所有请求,这种方式是最暴力但也最有效的系统保护方式。例如秒杀系统,我们在如下几个环节设计过载保护:机会检查,库存检查,下单
在最前端的 网关
上设置过载保护
,当机器负载达到某个值时直接拒绝 HTTP 请求并返回 503 错误码,在 Java 层同样也可以设计过载保护。
拒绝服务可以说是一种不得已的兜底方案,用以防止最坏情况发生,防止因把服务器压跨而长时间彻底无法提供服务。像这种系统过载保护虽然在过载时无法提供服务,但是系统仍然可以运作,当负载下降时又很容易恢复,所以每个系统和每个环节都应该设置这个兜底方案,对系统做最坏情况下的保护。
依赖隔离-熔断
熔断器与保险丝有些类似,当电流过大时,保险丝自动熔断以保护我们的电器。这里的熔断也是一样,当服务,光CPU就用了几万核。。。让我当场就震惊了。。。也给我看了下架构和服务的图,确实非常非常牛逼!目前京东这边在备战春晚红包,流量按照双十一的十倍以上去备战,真心期待后面有关于这次备战的分享~~
今天关于应对高流量,我就说到这了,后面有时间还会补点细节
关于下单,回滚订单,定时取消订单等可以看我后面写的这个https://www.jianshu.com/p/a844a1592902
关于有效订单的高并发问题可以看https://www.jianshu.com/p/552c4093832e (需要先看上面再看这个)
姓名:
年龄:
电话: