背景
零售行业通常会面临618、双十一、周年庆等活动。在面对这些重要的活动通常会担心资源是否需要扩容?应用能否抗住大并发的请求?
本人曾面对过几千大并发请求和客户这边搞活动出现问题的经验教训。希望能通过这些经验教训带来的优化改善能帮助更多的企业去解除搞活动时带来的焦虑。
解决方案
搞活动前我们要做一些准备工作,这些工作能有效避免我们的应用在搞活动时出现的各种状况。
首先,我们要准备一套和生产一致的环境作为压测使用。压测的目的就是模拟实际活动的请求,看看是否能抗住活动带来的并发压力。这里要注意的是,压测必须按实际可能的请求来,如果只是单纯的压几个活动中涉及接口是无法完全暴露真实请求可能出现的问题的。
其次,我们资源架构层面需要做如下准备:
01所有资源按照压测后由DevOps和压测人员以及研发负责人评估后给出资源的配置,包括容器的limit限制。
02虚拟机和K8S环境要求开启弹性伸缩,弹性伸缩的配置由DevOps和研发负责人评估后给出。
03数据库和其他中间件如果是共享实例需要评估如果出问题影响面大不大,如果影响面大需要在活动前至少一周做迁移,待活动后再迁回。如果活动会在一年内频繁开展建议单独实例并降低配置。
04云上数据库需开启读写分离功能,并且提前一周左右测试确认数据的一致性问题。
05云上数据库如果无法通过压测确认配置则需开启弹性扩展配置,并确认弹性升配的中断时间应用可接受。单独实例开启,共享实例不开启。
最后,应用层面要做如下准备:
01使用容器应用网关的,需开启熔断限流。并进行测试评估开启后触发的影响。用于确保应用不会被打爆。指标由DevOps和压测人员以及研发负责人评估后给出。
02如果有非正常的请求,应用层面需做Block防护,例如同一个用户ID同一秒发出超过10次优惠券请求的API,我们认为是非人为操作,需Block账户。
03如果有大量正常请求访问应用,应用层面可以设置排队页面缓存,按请求进入的先后次序分批放请求到后端缓存或数据库。比如一次放500个请求,处理完了再放500个。这样既可以避免应用奔溃也能避免后端缓存或数据库扛不住。
04如果有大量正常请求是到数据库取同样数据的则要把这些数据在第一次请求后放到缓存里,请求先到缓存,缓存里没有再到数据库,数据库有更新让请求到数据库来拿数据,缓存更新后再恢复到缓存取数据。这样可以减少数据库的压力。
05根据压测反馈的慢SQL,提前建立好必要的索引。
06提前load可能的热点数据进Redis,或者延长过期时间。
07对于key在redis不存在,数据库也不存在的数据,策略可以是赋值null写回redis,防止以不存在的id恶意攻击打垮数据库。
总结
活动前的准备工作要从资源架构和应用两方面着手去准备。以应用层面的优化准备工作优先,资源架构优化准备为辅。
因为资源本身并不能解决大并发的问题,只是提供一个承载环境。如果有一些很严重的慢SQL,资源架构优化的再好也有会被打爆的一天。
所以,我们一定要把主要精力放在应用架构的优化上。两者结合我们将不再为搞活动而感到焦虑,可以专注于业务的推动。