严选促销中心价格计算体系的建设之路

每当大促,各大电商、品牌都会为消费者提供各式各样的活动,各类活动任意组合,将带来多样化的价格计算场景。如何满足业务发展同时,最大化的降低系统计算的复杂度?本文将为你揭秘严选商品价格计算背后的秘密。

1. 背景

商品的价格计算是促销计价系统根据用户身份、用户资产、商品享受的活动、优惠券、红包等计算商品的价格。在交易场景(购物车、结算页、下单)体现为实际支付价格,在导购场景(商详、列表)体现为预估价格。

随着严选业务、渠道的不断扩展,活动玩法千变万化,商品价格计算愈发复杂。原来的价格计算体系已无法快速有效的支撑新增玩法,需进行促销计价系统的独立建设,与交易、商城业务解耦。

2. 难点及解决方案

当前严选价格计算可归为3大类:当前的实付价、当前的预估价、某时间段内的预估最低价,需分场景提供实时价格计算能力、实时预估价计算能力、指定时间范围内模拟价格计算能力。有以下难点:

2.1 难点一:各活动的规则并未统一

目前参与计算的活动由不同业务组维护,短期内规则无法统一。意味对活动规则的解释过程和计算结果均存差异性。

解决方案:活动计算组件化—— 将单个活动计算过程封装成一个组件,对组件外黑盒。并对输入和输出标准化。

  • 计算项(计价输入):包含价格、优惠内容、来源、属性等影响价格变化的内容。
  • 单个活动计价输出:主要包含价格和记录价格变化过程的快照信息。
  • 全局上下文:存储互斥信息、每个活动计算的过程快照、分组信息。

2.2 难点二:导购场景的价格计算随时可能根据营销策略进行快速调整,对扩展性要求极高

如新增一种活动时,参与计算的顺序可能位于计算链的末端或中间。原优先级相同的活动,计算顺序也可能经常调整。

解决方案有以下两种:

  • 设计好全局的上下文信息,计价流程编排采取硬编码的方式,需改变顺序时更改代码即可。

  • 计价流程可配置:将计算的顺序放在文件中,每次计算时读取,实现无代码改动即可快速调整编排顺序。 

2.3 难点三:活动优先级矩阵互斥。

如上图所示,活动与活动直接可能的优先级关系复杂:

  • 互斥:若商品能参与活动A,则一定不能参与活动B。

  • 可配置:商品能参与活动A,能否参与活动B,由活动创建人配置。

  • 最优价:商品同时能参与优先级相同的多个活动,选价格最低的

解决方案:

2.4 难点四:交易场景的价格计算属于核心逻辑,涉及到用户资产。需最大程度保证计算结果精准度,防止对严选和买家造成损失。

解决方案:

  • 热点活动数据采取多级缓存。

  • 对计算中的易出现资损的过程进行监控和报警。

  • 增加场景-组件级别降级机制,保证核心计算链路的稳定性。

3. 价格计算引擎的诞生

新的计价服务,需要满足以下几个目标:

  • 支持快速扩展新的营销玩法;能无感的从原计价流程中移除某个活动。

  • 支持快速调整计价顺序。

  • 性能:导购场景具有极高的RT要求和吞吐量要求,交易场景需保证极高的系统稳定性。

  • 最重要的是:提升研发效率、降低迭代过程中的影响辐射面。

3.1 具体实现

我们借鉴了流程类引擎的思想,并结合严选活动价格计算的现状,采用了:组件化、计算流程可配置、可插拔、计算过程场景化的解决方案。包含以下几个核心的模块:

3.1.1 计价pipeline

  • 单个pipeline内计算节点按顺序执行;单个计算节点内部,计算单元按顺序执行。

  • 计算节点内,从多个计算单元的计算结果中选出优先级最高的,并将非最优的活动计算结果、过程快照从上下文中移除。

  • 组件互斥:组件1与组件2互斥——商品真实参与了计算单元1的计算(组件1计算后,价格发生变化),则不再参与计算单元2的计算。

3.1.2 计价泳道处理器

计价泳道是指模拟计算商品某段时间T内的最低价时,需计算出时间T内所有可能出现的价格。因此需模拟可能出现的用户情况,我们定义每种身份为一个计价泳道。

确定计价泳道后,先获取该身份在时间T内参与的活动。以下5个活动的在时间T内的有效时间为:

  • 活动A:时间区间1;

  • 活动B:时间区间1+时间区间2;

  • 活动C:时间区间2;

  • 活动D:时间区间3;

  • 活动E:时间区间1+时间区间2+时间区间3

处理后时间片如上图所示。

经过计价泳道处理器处理后,某身份下每个时间片内参与活动已确定,剩下的交个计算驱动器。

3.1.3 计价驱动器

实时计算:直接获取当前能参与的优惠,交给pipeline处理

模拟计算:先根据场景获取对应的计价泳道,在计算各时间片内的价格(交个pipeline处理)。

3.1.4 配置管理

服务运行中调整活动计算顺序并实时生效不是核心问题,外加安全考虑,我们将编排信息放在json文件中,应用启动时会加载某个场景下的配置到引擎中。

以下为某个场景计价pipeline的配置(举例,不为真实配置)。

[    [        {            "componentType": 1,            "componentName": "限时购计价组件",            "conflictInfo": [                "5"            ]        },        {            "componentType": 2,            "componentName": "特价计价组件"        }    ],    [        {            "componentType": 3,            "componentName": "N元任选计价组件"        }    ],    [        {            "componentType": 4,            "componentName": "全场类满额减计价组件"        }    ],    [        {            "componentType": 5,            "componentName": "邮费计价组件"        }    ]]

计价组件1和其互斥信息构成了单个计算单元。计算单元1和计算单元2构成单个计算节点。

商品经过1和2的处理后发生价格变化,那么只能择出最优作为该计算节点的输出。(数字编号代表计算单元)

商品经过了1的处理且发生价格变化,则不参与5的计算。(数字编号代表计算单元)

3.1.5 整体设计

输入适配层接收参数后,将其转换成引擎入参后开始引擎计价过程,引擎输出结果经过结果适配层处理后对外输出。

4. 总结与展望

    • 截止目前,全新的价格计算引擎已为严选购物车、组单、下单等交易场景提供商品的计价服务。

    • 导购场景: 商详、列表、推荐等正在接入中。2021年的双十一,价格计算引擎将支持严选主站所有场景的商品价格计算。

    • 本文重点介绍价格计算引擎的设计思路。相关的并发设计、缓存设计、落地过程中遇到的问题及解决方案会陆续分享。

    • 在后续的规划中,促销团队会对活动规则进行重新设计并打造符合严选活动特色的规则引擎,进一步完善严选促销技术体系。 

原文地址:https://www.cnblogs.com/purple5252/p/15166436.html