我认知的电商在大促活动下的架构体系

我认知的电商在大促活动下的架构体系

薛定谔的汪

前言

每到双 11、618 等大促月时,各大电商是如何应对海量并发请求的呢,今天总结归纳下这背后的技术架构体系,并列举出我们技术人员面临的一些挑战,如何克服解决。

电商整体架构

概述

从组织架构到技术架构,当前各大电商系统基本趋于中台化。中台在2015由阿里提出,其实是一种企业 架构而不是单纯的技术层面,目前几乎各大电商都进行着中台化的建设。

中台没有什么神秘的,说到底,中台就是对 “共享”、“通用” 理念系统化的归纳和总结。

  • 重复功能建设和维护带来的重复投资
  • 烟囱式建设造成系统壁垒,数据孤岛
  • 业务沉淀促进可持续发展
  • 大中台小前台快速响应市场的需要

image-20210318122506676

上层业务

即大中台,小前台的前台,电商中直面用户的B2B,B2C等各个业务线。

业务中台

业务中台基于公共服务的沉淀,需要收敛一些基础的业务服务,如商品、订单、会员、库存、财务、结 算等等。

数据中台

数据中台不是一个平台,也不是一个系统。数据仓库、数据平台和数据中台是有区别的。简单的举例: 数据平台可以理解为数据库,数据仓库类比为报表,而数据中台更贴近上层业务,带着业务属性。

技术中台

与业务无关的基础沉淀,中间件,系统框架,监控,日志,集成部署等等

运维中台

不一定存在,系统运维相关的内容,硬件,机房,包括企业云平台的建设等可以划分为单独的运维中台

面临挑战

  • 高性能:提供快速的访问体验。
  • 高可用:网站服务7*24正常访问。
  • 可伸缩:硬件弹性增加/减少能力(快速扩容与释放)。
  • 扩展性:方便地增加/减少新的功能/模块(迭代与服务降级)。
  • 安全性:安全访问和数据加密、安全存储等策略。
  • 敏捷性:快速应对突发情况的能力(灾备等)。

内部瓶颈

  • 木桶效应:水管最细的地方决定流量,水桶最低的地方决定容量(QPS压测调优为例) 。
  • CPU:序列化和反序列化、高频日志输出、大量反射、大量线程的应用 。
  • 内存:使用内存的中间件或服务,如redis,jvm大量对象堆积内存的应用等 。
  • 带宽:大流量高并发环境下,用户访问量激增,造成网络拥堵 。
  • 磁盘IO:文件上传下载,数据库频繁读写,不合理或大批量的日志输出。
  • 数据库连接数:应用服务器连接池大批扩容,警惕底层数据库、Redis 等连接数瓶颈。

外部瓶颈

  • 短信:短信延迟与送达率问题, 可以搭建短信平台, 多家渠道做路由和切换分流。
  • 支付:银行支付与回调延迟,搭建支付中心,对接多支付渠道。
  • 快递:快递服务对接(快递100)。
  • 外部云存储:文件访问、流量扩容。
  • CDN:静态文件采用 cdn 加速。

外部云存储:云存储文件访问, 流量扩容( 大家所使用的存储?nfs 的架构与事故)

CDN:外部静态文件访问提速服务(使用过的项目?)

应对措施

订单中心

异步化

场景:订单状态变更时,实时同步到数据中台、大屏展示等。

问题:需要注意订单异步化引发的乱序问题,一是传输阶段,二是消费阶段。

示例:

  1. Rabbitmq :可以在队列级保证顺序,单消费者消费一个队列可以严格保障顺序性,就是多一些 queue 而已;或者就一个 queue 但是对应一个 consumer,然后这个 consumer 内部用内存队列做排队,然后分发给底层不同的 worker 来处理。

  2. Kafka:分区级别顺序保障,只能保障投放和传输阶段的顺序性,然后 一个 topic,一个 partition,一个 consumer,内部单线程消费,单线程吞吐量太低,一般不会用这个。
    写 N 个内存 queue,具有相同 订单 的数据都到同一个内存 queue;然后对于 N 个线程,每个线程分别消费一个内存 queue 即可,这样就能保证顺序性。

过期订单

可以参考这篇:过期订单自动取消的几种实现方式

支付中心

一般会有一个支付平台,由于我没完整做过支付,所以只列出常见支付的问题以及解决思路供参考:

重复支付

应对方案:

  • 前端程序屏蔽,前端js触发按钮置灰或者遮罩提示(支付成功?遇到问题?),或者在支付方式选择页直接 跳转。

  • 后端处理,发现不同通道下的支付成功回调,抛消息队列或记录日志。

  • 数据修复: 首先查支付日志,确认针对同一笔订单收到了不同支付渠道的回调。

    其次,在支付平台管理后端可以查到入账记录,人工介入。

    最后对账阶段会发现对方多帐,我方补单时出现重复订单。

问题处理:

调取退款接口或者在支付渠道的管理后台操作退款(一定要多次确认无误)。

异常订单

未收到支付成功

场景: 用户明明支付成功,但还是显示未成功

问题分析: 一般支付渠道会间隔性多次回调支付成功链接,银行未回调的可能性比较小,着重排查开 单接口是否可用。如果可用追查日志是否出现异常记录。

应对措施:

订单支付结果查询:定时主动去查银行支付状态。

对账阶段可以查漏,程序自动完成补单,但是处理相对延迟。

回调延迟

场景:用户是期望支付完成的同时立马看到结果。但是中间多层远程的调用,可能发生订单状态更新延迟问题。

解决: 主动查询。在用户查看订单的时候,如果是类似“支付中”的中间态时,触发远程订单状态查询接口。比如支付完成后,用户在界面点击“支付完成”时,触发单笔订单支付结果查询

支付路由

背景:

保障支付可用性及支付分流,支付中心对接多家渠道

方案:

  • 支付中心对接多个支付渠道,支付宝,微信,各银行或第三方支付供应商。
  • 对不同用户,进入支付方式选择页时,做支付分流。
  • 做好监控统计,一旦某个支付渠道不可用或者延迟较大,切掉,下线,或者降权。

营销中心

概述

大促肯定伴随营销,一般营销中心所面对的主要是促销策略、优惠方式等业务上的架构问题。

营销活动:单品促销活动、套装促销活动、店铺促销活动,平台促销活动。

营销类型:满减、折扣、赠品、优惠券等。

业务复杂度高,一般遵循:“同类营销仅可选其一,不同类营销可叠加” 的规则。

赠品设计

先了解 SPU、SKU 的基础概念

赠品有两种设计方案,一种是不做单独的SKU,只有一个空的描述,设计简单,缺点是没有商品详情 页,无法给用户直观的查看和估值。

另一种是单独做SKU,赠品也会作为一个商品存在,与主商品关联,下单的时候将会自动加到商品列 表,价格降为0。这种更为常见。整个商品有完善的详情页,用户可以直接看到价格甚至单独下单购 买。

排他与优先级

检查同类别促销,将最大优惠力度的规则应用到订单,并且满足排他性,同类只享受其一。比如满10减 3,满20减5,那么用户购买大于20时,只减5即可。

不同类别不做排斥,如购物车整体满减后,不影响单个商品的折扣。在记录数据时,优惠要细化到每个 单独的订单明细上。退款也做到明细级别的单独退。

价格分摊

满减或平台券等优惠,在多个商品下单时,涉及到金额的分摊。即 优惠总额度/购物车总额 ,得到比例 后再按比例均分到每个商品。只有分摊才能在发生部分退款时退回真实金额。

但是这会涉及到一个精度问题。举例如下:满99减9活动,假设用户购买了 30+40+50=120,3件商品 应付111元。按比例折算的话,9/99取4位小数是0.9090,那么分摊后为 30x0.9090+40x0.9090+50x0.9090=109.08与实际支付金额出现偏差。这会造成财务无法平账。

解决方案:记账时在订单明细记录,将误差 111-109.08=1.92计入金额最大的明细,也就是50元商品 上。那么最终记账为:30x0.9090 + 40x0.9090 +(50*0.909+1.92)= 111

退单处理

退单后要同时恢复用户的权益,比如优惠券的再次使用,限购次数等。确保用户体验。

商品中心

  1. 限时商品下架控制:这个和过期订单自动取消的技术手段一样,不再赘述。

  2. 库存管理:

    普通商品可以直接借助数据库锁实现,一般分乐观锁和悲观锁两种方案,如果采用悲观锁(如select语 句带forupdate), 会带来很大的性能阻塞, 所以更多的采用乐观锁设计。

    乐观锁就是在最后执行库存扣减操作时,将事务开始前获取的库存数量带入到SQL语句中作为更新的 where条件,如果数量相等,则该条更新库存的语句成功执行返回update条数为1;如果不相等,则表 示该商品的库存信息已经被其他事务修改,需要放弃该条update的执行,采用重试处理。

    库存秒杀商品因为大批量的访问在一瞬间涌入,数据库扛不住。可以采用 redis缓存做decr处理,正常

    下单后,再使用mq异步更新到db。

技术中台

数据库优化

数据库层的调优一般发生在大促之前的预备阶段,大促开始后再优化已经来不及了。

总结下主要有几点:

  1. 在大促开始前梳理耗时查询业务,对关键业务压测。

  2. 开启mysql的慢查询日志(两种方式)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #配置文件方式,需要重启mysql 
    #日志文件位置
    log-slow-queries=/opt/data/slowquery.log
    #超时时间,默认10s long_query_time=2

    #临时开启,不需要重启
    set global slow_query_log=on;
    set global long_query_time=2;
    set global slow_query_log_file=‘/opt/data/slow_query.log’;
  3. 借助 explain查看sql执行计划,对sql调优。

缓存优化

策略

  1. 热数据预热:常规缓存设计趋向于懒加载,大促期间的热点数据尽量做到预热加载。比如某个促销专题,不要等待活 动开始的一瞬间再读库加缓存,搞不好引发击穿。
  2. 细粒度设计:集合与单体分开存储,缓存结构细粒度化。如某个推荐商品列表,常规存储一个key,value为整个商品集合。优化为列表与每个商品详细信息设置两个独立缓存值,在查询环节组装。新增一个推荐则失效列表,修改商品则仅仅失效当前商品缓存。这样做的好处是缓存存储颗粒度变小,当数据库修改时可以降低缓存的修改冲击。
  3. 可用性:缓存穿透、缓存雪崩等。

多级缓存

优化缓存体系,对关键业务请求,如商品详情页,采用多级缓存处理

分流与限流

CDN的引入本身起到了按ip分流的作用,但是我们可以在下层做到更细粒度化的控制。根据业务情况将 不同的请求分流到各自的服务器。

限流是 当系统超过一定流量后,超过的流量做直接拒绝处理,以便保护后 端的服务,原则就是要么不进来,进来的都正常服务。常见的限流算法有这几种:滑动窗口、计数器、漏桶、令牌桶。

限流算法参考此篇:降级与限流

业务分流

根据不同的业务线分发请求,配备二级域名如b2b.xxx.com,b2c.xxx.com,或者在nginx软负载层针对 不同虚拟主机名做upstream分发

大促期的活动页,或者促销专题页面,采用新访问入口和机器部署,与主站分离。活动结束后也利于 机器资源的快速释放。

终端分流

按不同的请求终端分流,在header头的user-agent中可以捕获用户的访问终端。android,ios,pc, 根据不同终端设备,做流量分发,到不同的应用机器。同时方便对用户终端流量的监控和统计。

nginx限流

Nginx中使用 ngx_http_limit_req_module 模块来限制请求的访问频率,基于漏桶算法原理实现。

网关限流

从代理服务器放进来的流量,会进入应用服务器,第一道关卡是微服务的网关。应对大促,针对各个微 服务具体业务具体分析,配备对应限流措施。zuul和springcloud gateway是团队中最常遇到的网关组件。

服务降级

当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单 的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。是一种舍车保帅的策略。

比如平时客户来我的店铺购买衣服。平时可以试穿,给出建议,帮助搭配,最后下单支付,送用户祝福 卡片等。双11大促则简单粗暴响应下单支付收钱发货。其他不太重要的服务关闭开关,腾出资源让位主 交易流程。

服务降级可以从前端页面,后端微服务两个点着手。

页面降级

很好理解,针对页面元素处理,将不重要的操作入口置灰或屏蔽。平时调用后端接口实时呈现数据的地 方替换为静态页也可以理解为一种降级操作。

微服务降级

配置接口开关,并通过配置中心可以灵活开闭。必要时关闭开关,屏蔽接口的实际查询,直接返回 mock数据。

快速熔断

快速熔断可以认为是在应对突发情况时,对服务请求结果准确性的一种妥协。避免因单一服务垮台导致 整个调用链路崩溃。常用手段如下:

抛异常:这种处理需要上层配备异常处理机制,在捕获异常时,导向错误页、等待页或稍后重试 等。 返回NULL:简单粗暴,可能会出现空白结果,并不友好。 调用Fallback处理逻辑:更人性化的手段,也最常用。为每个业务配备一个备选方案。

举个例子:商品页或订单详情页面,一般都会有猜你喜欢这个模块,通过对用户的购买行为、浏览记录、收藏记录等等进行大数据分析,然后给每一个用户推送自己可能喜欢的商品。在双11大促背景下, 如果推荐服务压力过大,出现服务出错、网络延迟等等之类突发情况,导致最后调用服务失败,则可以 配备一个fallback,直接返回当前商品同类别下的几款商品,作为备选方案,这比抛异常或者返回null空 白页面体验要更优。

安全性

大促前做好安全防范。常见的DDos,Arp,脚本等攻击平时也会存在,日常防范已经配备。大促期间需 要注意的可能更多的是业务层面的入侵,比如抢购或秒杀时的恶意刷接口。

实名制,限制单用户,单ip等维度下的频次

必要的地方添加验证码(图片复杂度升级,或滑块等新型方式)

黑名单机制,一旦发现恶意行为,列入黑名单,并自动维护

  • Title: 我认知的电商在大促活动下的架构体系
  • Author: 薛定谔的汪
  • Created at : 2020-01-15 19:44:48
  • Updated at : 2023-11-17 19:37:37
  • Link: https://www.zhengyk.cn/2020/01/15/architecture/e-commerce-big-sale/
  • License: This work is licensed under CC BY-NC-SA 4.0.