业务背景
平台主要售卖电子商品和少量特定的实物商品。
经营模式,主要分为平台商家和自营店,自营店的流量占整个平台业务的50%以上,我负责自营店交易履约相关业务。
以前的架构,平台交易和履约中心是所有流量共享,在发品的时候,可以针对产品的归属(平台商家/自营店)进行打标,后续可以针对产品的归属进行流量染色和路由。
下图以正向交易为例
PS:下图简化了整个交易的核心链路,其他域还有产品域、商品域、资源域、购物车域、出行人域、凭证域、商家域等很多强依赖以及弱依赖的相关域,后文所提到的商品和产品在本文的语义可以理解为一样的(实际上,在平台业务定义上,商品为C端所属,商品有自己的特别属性,比如:零售价,商品详情等;产品为B端所属,产品也有自己的特别属性,比如供应商、结算价、成本价等)
这个“采购平台”历史悠久,领域边界模糊,代码和技术腐化严重,对后续的业务支撑非常不友好。
考虑到疫情结束,业务前景向好,于是,在慎重决定下,要在原有的平台架构上,构建一套涵盖交易、履约、产品、资源、合约、直连、风控、计费结算等多个领域的全新供应链体系,期望能在短暂时间内,能够将原有的业务流量平滑迁移到新架构上,并且新架构在未来能够友好的扩展新的业务模式,显著提高平台收益。
因为平台主要售卖电子商品,几乎所有的商品走的都是线上履约方式,所以,交易和履约以及逆向业务都收敛到了我这里。
关键词:电商、供应链、交易履约、采购中心、订单中心、系统设计、技术方案、高并发、分布式
工程难点
时间
Question:这个新架构是倒排需求,第一版迭代周期只有三个月。在保证工程质量的情况下,需要在三个月之内完成:需求评审 - 技术方案评审 - 研发 - 自测 - 联调 - QA - 上线 - 切流,并且能够完全承接旧系统的业务流量。
Answer:敏捷开发、做好规划、风险把控、人力协调、视死如归、我是牛马。
业务
Question:旧系统的业务架构单一,新架构的业务复杂多变,未来预期很高,所以在系统设计之初,就需要具备一定的扩展性,在领域设计时,也要处理好领域边界和领域模型的建设。
Answer:深学平台全链路业务;广学行业内相关业务和解决方案;向前辈求学问道,无论如何先把东西学到手。
技术
Question:系统的流量和未来预期的流量很高,每天增量的订单就有千万级别。
- 新系统上线之后,如何将旧系统的数据和流量平滑迁移至新系统?
- 面对复杂业务架构,如何保证系统具备良好的业务扩展性?
- 面对复杂技术架构,如何保证订单数据的一致性?产品数据的一致性?
- 流量会集中在某一天或一天的某段时间,如何保证系统的可用性和稳定性?
Answer:具备领域驱动知识、分布式解决方案、行业解决方案、高并发场景解决方案;深入理解集团中间件。
组织
Question:平台侧的团队变动频繁,一套平台工程经历了十几个团队,业务逻辑不透明,平台侧的研发同学新人居多,接入很漫长,心理压力大,再加上组织架构的隔离性比较高,平台侧的问题很难推动。
Answer:提供足够的情绪价值、夸她、爱她、包容她;交付进度阻塞必须风险上升,一切以解决问题为主。
业务演进
之前的“采购平台”仅支持平台自营店,新的架构希望能够扩展业务模式,所以在原有的业务模式上,给新架构设定了三个目标。
目标核心
- 打通供应链交易履约逆向链路,完成流量的平滑迁移
- 在原有的业务基础上,具备横向纵向业务领域的扩展
a. 在原有类目的基础上,能够自由扩展更多的业务类目
b. 在原有销售模式的基础上,能够扩展更多的销售模式(直销、分销、代理等)
c. 在原有业务模式的基础上,能够扩展更多的业务模式(秒杀、二次预约、囤货、预售等)
d. 在原有支付体系的基础上,打造域内的资金池等体系(预付款、授信等) - 能够支持线上计费结算,完全替代线下手工对账体系
演进阶段
在初步设定好新架构的目标之后,规划了一下业务演进的方向,大致分为了 3 个阶段。
- 第一个阶段:构建高可用、高扩展的技术架构,并支持单业务类目单销售单支付模式,完成上线切流。
- 第二个阶段:持续建设系统的稳定性,并支持单业务类目多销售模式单支付模式。
- 第三个阶段:针对核心业务进行极致优化,并推动系统平台化发展,支持多业务类目多销售模式多支付模式。
收益体现
新架构的收益总结
经济收益:
- 针对自营店,2023年的GMV大概为 n 亿元,经过业务战略的调整和完善,2024年的GMV保守估计已达 2n+ 亿元,完成了自营店收益跨越式增长。
- 基于业务资源背景,打通分销销售渠道,一年入驻 分销商/代理商 x 家,接入 核销商/系统商/供应商 y 家,资源数量级涌进国内行业前列。
- 分销和代理渠道的GMV在一年内已远超自营店2023年的GMV,2024年保守估计已达 1.3n+ 亿元,成为平台经济收益新来源。
技术收益:
- 解决了高并发下的系统可用、数据一致等问题,解锁集团域内中间件新玩法。
- 沉淀出一套完整的交易履约技术方案、系统治理方案以及业务领域架构方案,实现域内相关业务可复用能力。
团队收益:
- 项目初期,周末加班双倍工资,项目稳定上线之后,每个人获得1~3个月工资的项目奖金,提升了团队人员流动的稳定性。
- 团队在前3个月一直保持007高强度的工作节奏,无一人缺席,倡导的狼性文化得到验证,提升了团队的凝聚力。
- 业务相关数据成指数级增长,带来了当下和未来及其可观的收益,供应链侧研发团队由 n 人,已经扩展到目前的 2n+ 人。
业务设计
交易角色
- 对于整个平台的交易角色,可以划分为:C - B - P - S
- 对于整个供应链领域,可以划分为:B - P - S
C:用户|B:自营店/分销商/代理商|P:采购平台主体|S:供应商
交易属性
- 对于自营店,在 B - P 阶段的交易,本质上是虚拟交易。
- 对于分销商和代理商,是真实支付的线上交易。
交易阶段
在供应链交易这个领域,是两阶段交易:BP & PS。流量从 B 端过来,可能会涉及到拆单的操作,映射到系统设计上,BP 阶段产生的订单定义为主单(BP 单),主单拆成的订单,也就是 PS 阶段产生的订单,定义为子单(PS 单)。
领域设计
在设计之初,需要将各个领域边界划分清晰,方便后续的系统迭代和架构升级。
领域架构
整个新团队,职责划分非常明确和清晰,在经过数次的“脑暴”后,领域框架选型成了最大的问题。以前研究过Axon几年,并且有过Axon在大型区块链交易系统,从0到1的实战经验,所以在领域架构选型上,首推Axon作为整个团队的领域基础框架。
但是,在 “技术落地讨论会” 中,发现团队内的同学们,技术分散严重,只有一半是做过Java相关业务的,业务分散也很严重,只有一半是做过/了解过电商相关业务的。因此,大家对行业的业务领域和这些领域驱动框架,了解的不是特别多。
为了让项目尽快落地,在领域框架设计上,并没有严格采用DDD的思想,但是在系统设计上参考了Cola这类框架的整洁结构和Axon这类框架的事件驱动设计,结合平台的业务,将“脑暴”后的领域模型,不断推演,最后将传统的领域驱动框架进行抽象和精简,就有了现在的基础领域架构。
scc-starter是在大学开源的一套适配器组件的域内升级版,方便灵活,一键启动。
领域划分
最开始绿色的领域,都是打散到红色领域中,第一版上线以后,发现各个领域随着业务迭代愈发臃肿,于是及时做了调整。
核心域:订单域,支付域,资金域,履约域,退款域
支撑域:产品域,合约域,超时域,消息域
领域能力
订单域:预下单、收单
支付域:正向付款、逆向扣款等
资金域:资金流
履约域:预定资源、确定资源、服务完成
退款域:申请退款、快速退、强制退、退款回调
产品域:产品查询、库存扣减、库存回补、拆单、合单、Hold 单
合约域:合约信息查询、合约合法性校验
超时域:集团内部通用的技术解决方案,旨在解决分布式事务(tcc)、消息丢失、任务补偿等
消息域:领域事件驱动
领域事件
领域模型
实体对象:采购单、资金单、履约单、退款单、预付款信息、预付款详情、调度任务
值对象:联系人信息、账户信息、合作关系、分销商与供应商信息、操作日志、退款规则、POI、凭证信息、出行人信息以及渠道信息
数据模型设计是整个系统最核心的环节,设计之初要保证数据结构具备足够的扩展性和容忍性。比如订单是否需要聚合、订单模型是否能够支撑未来的业务模式等。
订单状态
订单态:订单初始化 - 订单交易中 - 订单交易完成 - 订单交易关闭
履约态:履约单初始化 - 履约单已创建 - 供应商创单成功/失败 - 待核销 - 部分核销 - 全部核销 - 履约完成
支付态:未支付 - 已支付
退款态:未退款 - 退款单初始化 - 已申请退款 - 同意/拒绝退款 - 退款关闭 - 退款成功
资金态:未付款 - 已付款 - 付款成功/失败 - 分账完成/失败 - 结算完成/失败 - 交易完成/失败
系统设计
平台全链路交易履约时序图
新架构的预期流程,如下面的时序图所示(这是相对复杂的一种情况)
这个全链路时序图,屏蔽了很多交易系统弱依赖应用,希望能让读者轻松看懂整体的交易履约流程。
整体设计图
整体是两阶段交易,正向交易主单驱动子单,逆向履约子单推动主单,从下图来看:
第一阶段:收单 - 支付,归属于BP交易范畴,因为平台和分销商合作的性质不同,支付能力基于第三方支付平台和域内资金池等方式,但是整体而言都算是实时支付。
第二阶段:预订资源阶段本质上就是系统商创单的阶段,如果创单成功,会记录资金流水,同时也会给计费结算平台发送计费事件。这里其实也是基于平台和系统商合作的性质,因为平台和所有的系统商资金都是T+1月结。
解决方案
收单服务治理
收单服务接口,是整个交易平台的流量口子,在收单过程中,会和域内域外多个服务进行交互,涉及到各种复杂的业务逻辑。比如合约服务、产品中心和直连网关等,这些服务都是交易平台强依赖的,这些服务不可用,也会导致交易平台不可用,本地基本上是没有什么降级方案的。
除了本地服务基本的代码优化(减少调用链路,优化代码逻辑执行顺序,将阻断校验流程前置,优化数据结构和算法,优化查询逻辑,减少IO次数,利用本地缓存等),合约服务接口性能、产品中心服务接口性能以及第三方支付平台的接口性能,成为了影响收单服务接口性能的重要因素。
- 合约服务:查询合约信息等
- 产品中心:查询产品信息、扣减库存、回补库存等
- 支付能力:支付宝代扣(查、付、退、取消、校验等)
第一阶段开发周期短,核心是如期交付上线,接住旧系统的线上流量,为后续的业务扩展带来可能。根据已有大KA的要求,收单RT在6秒之内,收单服务即为可用,上线之后,收单服务的RT常态化Max为5秒。
治理前后各项指标概要:
- 总响应时间(RT)显著提升:
治理前:4700ms
治理后:250ms
治理效果:提升了18倍 - 本地计算响应时间(RT)显著缩短:
治理前:200ms
治理后:30ms
治理效果:缩短了6倍 - 查询产品信息响应时间(RT)大幅减少:
治理前:800ms
治理后:70ms
治理效果:提升了11倍 - 查询合约信息响应时间(RT)大幅降低:
治理前:1200ms
治理后:60ms
治理效果:提升了20倍 - 校验支付能力响应时间(RT)极大缩短:
治理前:500ms
治理后:10ms
治理效果:提升了50倍 - 预占库存响应时间(RT)显著减少:
治理前:2000ms
治理后:80ms
治理效果:提升了25倍 - 单机QPS(每秒查询次数)大幅提高:
治理前:40qps
治理后:800qps
治理效果:提升了20倍 - 集群Max QPS显著提升:
治理前:1100
治理后:4000
治理效果:提升了4倍 - 收单Max QPS显著提升:
治理前:300
治理后:1200
治理效果:提升了4倍 - 服务器数量优化:
治理前:40台(4C8G)
治理后:21台(4C12G),包括10台、8台和3台不同配置
治理效果:服务器数量减少,配置提升。
库存扣减
https://blog.csdn.net/CSDN_SAVIOR/article/details/142887066
产品查询
https://issavior.blog.csdn.net/article/details/140734888
支付能力
正式创单之前,会进行支付校验,域外的支付服务,非常不稳定,因此,增加了重试、补偿等容错手段。为了彻底解决这种问题,提高成单率,平台在域内打造资金池,分销商可在平台预付款,每次支付从资金池扣减。
流量平滑迁移
https://issavior.blog.csdn.net/article/details/141201666
业务扩展能力
https://issavior.blog.csdn.net/article/details/140891892
https://issavior.blog.csdn.net/article/details/140903785
系统数据治理
订单数据一致性
https://issavior.blog.csdn.net/article/details/141275722
订单全局唯一ID
https://issavior.blog.csdn.net/article/details/141279168
存量数据
针对旧采购系统的订单数据,新交易系统不必感知。
旧系统的存量数据和新系统的增量数据由买家域和卖家域自行处理这些数据即可。处理数据需要注意数据的一致性,在平滑切流的过程中,新系统可能会存在旧系统的数据,域外在同步数据的时候可以做一层清洗和过滤。
数据的分片
随着分销商和供应商资源的不断涌入,流量在一段时间内成指数增长,庞大的订单数据该如何存储?这里的方案是采用分库分表(未分区)和读写分离架构,将数据和流量打散。
将采购单表、资金单表、履约单表、任务表进行水平拆分,设计到相关的技术是TDDL,核心原理和Sharding-JDBC差不多。
拆分规则
因为采购单数据不涉及到实时查询,所以根据订单ID直接取模即可。
分片规则
根据以前业务的数据规模以及业务方针对未来的流量期望,每天的增量订单会有千万级别。
根据集团的数据库和存储引擎性能,最终采取的分库分表方案如下:
8库 - 32张表/库 - 256张表
数据清理
供应链交易履约平台的订单的生命周期比较短,目前已知订单最长的生命周期是一个月,所以可以将数月之前的数据同步到冷库中。
读写分离
准确的说,读写分离在交易系统上的实践是有风险的,交易系统大多为实时查询,如果因为大事务、网络抖动等原因,导致从库的数据同步有延时,那对于交易系统的稳定性是非常致命的。
这里读写分离主要是用在一些域内非核心应用(小二系统),给这些非核心且关键的业务透出一个口子,做一些必要操作,但是也要注意这些接口的稳定性,比如限流措施等。交易等核心业务,对于数据的实时性要求比较高,读写都需要在master节点上。
但是这样的设计显然不合理,应该要将这些依赖交易系统的非核心应用全部干掉,让他们通过其他渠道去获取数据,以此来提升交易系统的稳定性。
系统治理
流量分组
- 交易平台将自营店流量和分销/代理流量进行分组,避免销售渠道相互影响。
- 全链路服务将交易的流量单独隔离开,避免非核心业务影响到交易链路。
异常监控
针对系统和业务级别的异常,划分严重等级,做聚合告警(整合行业AI大模型,做智能监控),通知运营和研发同学,及时处理。
发布流程
上线之前,严格按着发布流程来,研发 - 自测 - QA - CR - 安全环境回归 - 观察 - 灰度发布 - 观察 - 分批上线 - 观察,而且CR务必经过Owner,血的教训。
埋点日志
针对各个交易节点,做全链路trace埋点,除了排查问题之外,还可以溯源,很多次,系统商服务的问题,无法追溯,导致结算出问题。
风控巡检
上线之后,发现系统商这服务说挂就挂,很不稳定,用风控巡检来对所有的系统商服务接口做探针探活,有问题就熔断掉异常系统商服务,服务存活后,再恢复系统商服务能力。
熔断限流
对外的接口,上线之前要进行服务接口进行压测,并根据压测结果,设置合理的限流阈值,防止服务挂掉。
日常工具
常见的不可抗拒的问题,需要制定相应的工具,遇到问题时可以提供给运营或者研发同学。
紧急预案
如果出现线上的问题,需要有止血措施,比如在上线之前,可以针对改动点增加动态配置开关,如果出现问题,可以秒级止血,即在1秒内关闭上线功能,然后在进行回滚以及问题排查等措施。
问题复盘
出现问题不要怕,要及时复盘、总结,不能秉持“少做少错,不做不错”的态度。
节前准备
针对于预知的流量(节假日、营销活动等)要做好扩容,值班人员必须保证问题响应效率和解决质量。
风险排查
成单率、消息堆积、磁盘内存、ES容量、数据同步延迟、慢SQL等。
提效秘籍
自己这几年用的还不错的复盘计划,分享一下,希望能对大家有所帮助。
结束语
本文对“交易履约平台”做了简单叙述,主要从宏观视角概述了繁杂业务中仅一条相对复杂的“交易”业务线的相关要点,当然,履约和逆向业务也是非常的好玩并且具备难点和技术挑战,若有机会,我将分享这些领域的心得。
期望本文能为初涉电商交易领域的小伙伴们提供一些有价值的启发。同时,希望各位老师不吝批评指正,指出文中的瑕疵与待改进之处。更期盼大家在评论区踊跃留言,共同交流心得、探讨问题,携手促进我们的成长与进步。