一 背景
今年的618大促已经如期而至,接下来我会从技术的角度,跟大家聊聊大促备战的底层逻辑和实战方案,希望能够解答大家心中的一些疑惑。
首先,618大促为什么如此重要呢?先从数据的角度简单做一下分析,以下表格罗列了我们历年大促GMV成绩单:
年份 | 618销售额(亿元) | 年销售额(亿元) | 618销售额占比 |
---|---|---|---|
2022 | 3793 | 33155 | 11.4% |
2021 | 3439 | 32970 | 10.4% |
2020 | 2694 | 26125 | 10.3% |
2019 | 2017 | 20854 | 9.7% |
2018 | 1592 | 16769 | 9.5% |
根据以上数据统计,我们可以得出结论:每年的618大促销售额约占全年销售额的10%左右。以2022年618大促销售额为例,大促期间,每分钟的销售额平均高达1463万元。因此,从技术角度来看,保证服务的稳定性是至关重要的。相信这些数据可以为您在大促期间制定任务优先级和做出决策提供有价值的参考。
二 挑战
大促期间系统的稳定性对于业务的正常运营如此重要,我们需要探讨以下问题:
影响系统稳定性的因素都有哪些?
稳定性要求与日常对系统的高可用要求有哪些不同之处?
面对各种不稳定因素,我们应该如何应对?
下面我们一起来分析和探讨这些问题。
1. 影响系统稳定性的因素有以下几个方面:
流量大小:大促期间,流量往往是平常的几倍甚至几十倍,这对系统的稳定性提出了极高的要求,一个小问题,在流量放大后,往往会演变成大问题;
数据量大:以2022年的订单为例,订单额达到了3.4万亿,在海量订单数据的场景下,一个简单的查询,都会变得非常具有挑战;
场景复杂:各类促销优惠、平台、商家、运营等各种营销玩法的叠加,使订单生产链路始终处于高负荷运算状态;
交付链路长:各端的流量分发、促销计算、加车、结算、提单、支付、物流配送、客服、售后等各个流程节点都需要保持稳定。如果一个服务99.9%的可用率,那么100个相关服务节点组合起来,可用率就只能达到99.5%了,而那0.5%的不可用,对应的都是大量的订单流失;
容忍度低:消费者要求良好的用户体验,商家需要促销快速生效,平台则要减少错误和资损,保护消费者和商家的利益。更高的期望和关注,带来的是更低的耐心和容忍度;
2. 在大促期间,对系统的稳定性要求更高,但与平常对系统的高可用性要求不同。这主要体现在以下几个方面:
时间紧迫:大促期间需要在短时间内保证服务的稳定性,通常没有时间深入技术细节;
视角不同:稳定性注重整体业务效果,而高可用性注重服务响应结果;
维度不同:实现业务稳定性保障通常是建立在系统高可用性的基础之上,并配合相关的服务运营策略,以实现更高维度的业务稳定性。
3. 接下来将重点围绕备战大促的相关思路和经验进行展开,以帮助您应对挑战并确保系统的稳定性。
三 稳定性保障
以下罗列了今年大促备战的部分措施:
上图里展示的各种备战项目,有方向性的指导,有流程上的规范,有落地层面的要求。下面我将从更细粒度的系统执行层面出发,提供一些备战策略。
正如前文提到的,大促期间的稳定性保障一般属于应急策略。目的是在保证系统稳定性的前提下,对问题的快速响应。我们将从应用、存储、运营三个视角,来探讨系统稳定性保障的应急措施。
3.1 应用视角
3.1.1 单元化
单元化部署是将应用拆分成多个独立的单元进行独立部署,有以下好处:
降低整个应用因某个单元故障而导致服务中断的风险;
降低故障排查的难度,因为可以快速定位出问题的单元并进行修复;
每个单元都可以独立维护和升级,这样可以降低整个应用因某个单元升级或维护而导致服务中断的风险;
每个单元都可以独立扩展和缩减,这样可以根据实际需求动态调整应用的规模。
为了保证服务的可靠性,我们需要在备战层面实现异地多活的能力,即要求服务进行异地多机房部署。考虑到异地跨机房调用的网络延时问题(例如北京到上海的往返网络延时大约为12毫秒),黄金交易链路的所有服务都需要本地单元化部署。因此,建议采用本地单元化优先的部署架构,并与其他异地单元化互为灾备。
另外,也要注意流量负载均衡策略,防止出现分组的调用流量不均衡,造成部分分组因流量倾斜,导致性能表现不佳的情况出现;
3.1.2 监控预警
预防和发现问题的最直接方式,需要关注以下几个方面:
监控粒度方面:监控按照层级分为底层中间件监控、依赖RPC监控、方法监控、机器监控、系统监控、业务监控、流程监控、整体的大盘监控;
监控的灵敏度问题。灵敏度过低会导致部分问题被延时暴露甚至被隐藏,而灵敏度过高则会造成信息爆炸,难以分辨信息的主次。因此,在实施监控前需要提前做好功课,确定合适的灵敏度;
监控的覆盖度方面:关注监控服务单元、监控指标梳理、监控触达方法。比如:监控需要覆盖容器数、资源指标、运行环境(JVM、线程池)、流量大小、限流值、上下游依赖、超时时长、异常日志、数据容量、模型规模、特征数量等,并可以进行时间维度的纵向对比;
监控的准确性方面:看可用率,需要看上游调用方的,可能200ms响应时长,对与调用方来说,已经属于不可用的区间了。看CPU繁忙程度,不能只盯着利用率,还要结合容器核数和CPU负载来分析;
预警解除方面:接到预警消息,及时排查并处理风险,切不可将小问题演变成大问题。先确认是单机硬件或网络问题,还是集群通用问题,如果是通用问题,能否通过服务调用链追踪技术快速定位问题点,确认好问题原因,才能做好应对预案;
3.1.3 日志打印
日志格式、日志级别、输出方式,归档策略,序列化方式,traceId策略等都需要进行合理设置,特别要限制重复日志和无效日志的输出,减少日志对机器资源的占用。比如:业务异常堆栈日志不建议直接打印,通过状态码统计结果就可以了;
3.1.4 快速失败
能够快速地检测和响应故障,帮助服务更快地恢复正常状态,从而提高系统的可用性和稳定性。实现快速失败,常见的技术手段如下:
线程池超时时间的设置,关键系统要拥有动态调整线程池运行参数的能力;
利用好工具已有的能力,比如:JSF,JimDB,JMQ等中间件也都支持超时失败的动态调整能力;
服务限流也是快速失败的一种实现策略,常见的微服务框架和物理网关一般也都支持类似功能;
总之,快速失败可以保护系统资源的合理分配,避免出现资源调度阻塞甚至全盘崩溃情况发生,是稳定性保证的重要手段。
3.1.5 服务限流
限流一定是基于系统的承载能力来进行的,整个服务调用链路上,遵循木桶原理,下面给出一些建议:
限流方式和阈值需要经过系统多轮压测验证,以确保数据指标的准确性。
对于业务聚合系统,主要依赖于第三方服务,通常没有存储层,瓶颈往往出现在应用服务本身。这种情况下,单机限流是比较好的方式,因为这种方式对于服务扩容或缩容非常友好。只需保证扩容的容器硬件配置与线上容器保持一致即可。
对于底层基础服务,瓶颈点往往在数据存储层,而存储层的扩容成本相对较高,实现起来也比较困难。在这种情况下,全局集中式限流是一个很好的选择,其目的是优先保证存储层的稳定性。
建议根据调用方的重要程度进行精细化限流运营,确保在极端情况下,具有优先保证核心业务可用性的能力;
3.1.6 业务降级
通常情况下,降级策略是一种防御性的应对措施,用于应对可预见的风险。这种策略可能会牺牲部分非核心能力,以确保业务的基本可用性。随着业务不断迭代,需要时刻关注之前的降级策略是否仍然适用,特别是在多人协作的系统中。
3.2 存储视角
下面从存储视角来看看稳定性保障方面的一些思路。
3.2.1 数据库
主从架构:这是最常见的数据库实例部署架构模式,目的是保证核心数据的高可用,防止出现单机故障,导致数据丢失的情况发生;
读写分离:对于大部分实时性要求不高的场景,可以将从库资源充分利用起来的,按照业务场景,实现写主库,读从库的架构模式;
事务隔离:MySQL默认的事务隔离级别是RR,但对于大部分应用场景,特别实在写频繁的场景,将隔离级别设置为RC级别,也能够提高数据库吞吐量;
分库分表:这里不是要求大促前进行数据库架构升级,而是说在大促期间,可以进一步将数据进行更细粒度的迁移,比如启动冷热数据的迁移任务;
慢查询:提前做好索引优化,比较重的查询,提前进行降级屏蔽,做好监控预警;
3.2.2 缓存
一主多从:核心数据需要关注部署架构的合理性,目的是保证核心数据的高可用,防止出现单机故障,导致数据丢失的情况发生;
能力扩容:缓存是否需要扩容,主要考虑两个因素,存储空间上限和IO流量上限。在达到上限之前,及时增加分片来提高容量上限;
主从双读:缓存主从部署架构的模式下,从分片也可以用来承接部分业务压力;
热点数据:热点数据需要及时消灭,否则容易引起节点性能的急剧下降,高版本的缓存客户端已经支持了热点数据的识别,并实现了热点数据进行本地缓存的优化;
大key问题:大key同样会导致集群性能的稳定性问题,核心业务需要考虑风险隔离,避免多条业务线公用一个缓存集群,尽量做到集群隔离;
3.2.3 Elasticsearch
双集群:ES虽然拥有数据容灾的能力,但在压力大的情况下,能够优化的空间有限,另一方面,集群节点故障的时候,分片再平衡也可能会影响可用率,所以重要的业务建议做双集群进行能力冗余互备;
慢请求:有时候慢请求会导致整个集群卡住,类似关系型数据库中出现锁库的场景。那么我们可以通过查询集群中的慢请求任务,若有必要可取消,以释放资源;
写控速:大量的写请求会比较影响查询性能,有时候可以适当的限制写速度,来保证集群查询的稳定性;
存储容量:集群对存储容量默认有根据不同的水位线进行保护,若超过水位线则无法再提供写入特性。需要监视集群存储占用情况,亦可根据实际服务器存储配置调高水位线;
3.3 运营视角
千里之行始于足下,再好的预案都需要贯彻执行到位,否则只能事倍功半。下面给出一些运营保障措施。
3.3.1 备战小组
站在系统或团队内看问题往往是有视野盲区的,还需要有站在更高维度看问题的视角,这就是备战小组。准则就是:及时响应、效率第一。从问题的发现、影响范围的控制、解决方案的推进到流程规范的执行,备战小组都扮演着不可或缺的角色。
3.3.2 军演压测
这需要协调上下游相关部门,组织协调成本很高,旨在模拟真实线上流量,以进行系统稳定性的压力测试。这是应用维度,稳定性保障预案的数据指标基础,如:监控指标,熔点阈值、限流阈值和机器扩容数等。
3.3.3 技术封版
上线封版,听起来往往让人难以理解,难道大促期间我们就不上线了吗?据统计,70%的线上问题是由于改动发版导致,大促期间,业务需求让步于系统稳定性保障,也是再三权衡的结果。
3.3.4 每日巡检/假期值班
作为系统自动巡检的补充,对系统定时定点的进行可用性检查。其目的是及时发现问题,降低异常影响范围。
3.3.5 应急预案
这是出现问题后的备用计划,备战是为了避免问题的发生,但如果问题真的出现了,应急预案将成为我们最后一道防线。关于应急预案相关的要求和操作,参照下图:
四 总结
本文从技术角度深入分析了大促备战的背景和重要性,重点介绍了备战期间稳定性保障的相关措施,包括具体的指导方向和落地细节。本文旨在回顾和梳理备战期间的关键步骤,以帮助我们更加从容的应对系统稳定性的挑战。虽然大促备战是一场紧急行动,但备战的效果离不开平时的协作共识和技术积累,过往的经验和教训,在此刻将得到充分验证。
作者:京东零售 刘慧卿
内容来源:京东云开发者社区