【高并发项目实战】自适应高并发复杂场景的订单拆分算法工具

简介: ​本篇文章带你打造一个自适应场景的交易订单合单拆分通用算法方案,根据现有技术的痛点,我们支付的时候设计一种自适应场景的交易下单合单拆分通用算法的方案,可插拔的场景组件提升扩展性和通用性就很重要。

前言

📫作者简介小明java问道之路,专注于研究计算机底层/Java/Liunx内核,就职于大型金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的架构设计📫

🏆CSDN专家博主/Java领域优质创作者、阿里云专家博主、华为云享专家、51CTO专家博主🏆

🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~

本文导读

本篇文章带你打造一个自适应场景的交易订单合单拆分通用算法方案,根据现有技术的痛点,我们支付的时候设计一种自适应场景的交易下单合单拆分通用算法的方案,可插拔的场景组件提升扩展性和通用性就很重要。

一、 技术难点以及为什么一定要实现自适应场景

现有业内或产品是否有类似的,现有技术是否有缺陷或不足或问题,我们支付的时候

网络异常,图片无法展示
|

交易系统为满足企业生产、销售、服务等需要,信息化模型复杂;为应对运营、管理和决策从而业务变化快;需要应对多商业模式的场景,例如多供应商、自营模式、入驻模式等;运营系统多样性,如O2O/C2C/B2C/。

随着业务不断迭代,每增加一个场景或者一个交易支付工具,交易模型就成笛卡尔积形式增长,下单、支付退款、结算业务将越来越难以维护和扩展。如果不能有效控制和管理,后续扩展都需要不断重复的进行原有工作,导致业务代码冗余,逻辑不清晰,不能有效的保证数据一致性,也会带来代码效率和开发效率等问题。代码可读性变差,同逻辑不同实现代码性能参差不齐的问题。

网络异常,图片无法展示
|

针对以上问题,设计一种自适应场景的电商下单合单拆分通用算法的方案,设计根据下单场景自适应交易合单的拆分订单信息、结算信息,通过顺序表存储可插拔的场景组件提升扩展性和通用性,使用持久层提升代码执行逻辑效率和数据一致性。

二、交易模型设计原理

对于复杂的交易模型,此设计整体上分为4个模块——分摊模块、事件模块、服务模块、数据模

1、数据模块

将复杂的模型抽象化,保留交易类型、交易流水信息、订单商品信息,如需要扩展信息,可根据已知信息通过业务场景,在数据获取更多的信息。以统一的抽象数据模型应对多样的复杂的场景,场景动态扩展,程序通过策略选择,统一迭代来自适应复杂场景。

网络异常,图片无法展示
|

2、事件模块

事件体系是交易系统内部抽象模型,定义了一个唯一的事件ID,支持同步异步执行,具有配置持久化机制、自定义异常重试机制、自动触发机制、监控报警等特点,将复杂逻辑代码和交易业务代码解耦。

网络异常,图片无法展示
|

3、服务模块

将数据模块、交易拆分信息在提供服务之前完成持久化,提供统一通用的服务接口,避免数据不一致,提高下单、退款、清结算、金额/数量分摊的性能与一致性。

网络异常,图片无法展示
|

4、算法模块

总体基于事件模块自动执行,将数据模块信息拆分,内置支付工具模块可支持配置的所有工具扁平化处理,过滤仅使用的工具。拆分主体根据配置规则,按照商品总金额占比模式拆分,对复杂交易模式进行统一集中处理,对防资损使用拆分金额/数量恒等于交易金额/数量的方式,对异常处理具有失败重试、失败监控告警、异常捕获等措施。最终通过此模块,服务各类复杂订单拆分、不同场景拆分的能力。

网络异常,图片无法展示
|

5、整体设计

整体业务处理流程图,首先我们拿到用户的行为,例如:下单使用了支付宝+商家券+满减活动+618活动+花呗+银行卡,出去拆分下单落库,优惠券的核销使用,我们将拆分逻辑使用异步API-Future进行开发,首先将拆分事件定义为一个 event 事件,此事件保存在环形缓冲器(ring buffer)这么做为了可以循环执行添加的事件,无需阻塞,这个时候在事件里面,实现自适应的拆分逻辑,并将拆分逻辑提供对外的服务接口即可,当此事件执行异常时,会进行落库操作

网络异常,图片无法展示
|

三、交易模型设计代码实现

1、发布事件

Disruptor是一个高性能的异步处理框架,或者可以认为是线程间通信的高效低延时的内存消息组件,它最大特点是高性能,其LMAX架构可以获得每秒6百万订单,用1微秒的延迟获得吞吐量为100K+。disruptor设计了一种高效的替代方案,我们使用 disruptor.getRingBuffer(); 构件高并发容器

/**
     * 发布事件-异步执行
     *
     * @param orderEvent 事件
     * @param isAsync    true-异步 ,false-同步
     * @param context    上下文
     */
    @Override
    public void publishEvent(OrderEventBean orderEvent, Object context, boolean isAsync) {
        try {
            // 实时异步且异步事件可重复处理时事件入库+redis
            // 信息入redis
            // 执行异步事件
            if (isAsync) {
                RingBuffer<OrderEventBean> ringBuffer = disruptor.getRingBuffer();
                ringBuffer.publishEvent((event, sequence, groupId, orderId) -> ConvertBeanUtil.copyBeanProperties(orderEvent, event), orderEvent.getEventGroupId(), orderEvent.getOdrId());
            } else {
                // 执行同步事件
                logger.info("publishEvent方法orderEvent={}", orderEvent);
                EventProcessorUtil.run(orderEvent);
            }
        } catch (Exception e1) {
            logger.error("publishEvent error e1 =", e1);
        }
        logger.info("publishEvent end");
    }

2、逻辑模块

计算分摊数量工具的核心逻辑,分摊逻辑:单笔子单 支付方式 支付金额 / 该支付方式总订单积分支付金额 = 数量,最后一笔子单使用减法 (订单总数 - 分摊总数) = 剩余分摊数 < 最后一笔分摊数 ? 剩余分摊数 : 最后一笔分摊数主要流程:1、先对list<...Detail>根据优先级排序,2、按顺序分摊,不能超过剩余的总数量,最后一笔取剩余,退款不能超过交易,3、获取下单时的支付工具,4、计算

/**
     * 计算分摊数量的工具
     * 分摊逻辑:单笔子单 支付方式 支付金额 / 该支付方式总订单积分支付金额 = 数量
     * 最后一笔子单使用减法 (订单总数 - 分摊总数) = 剩余分摊数 < 最后一笔分摊数 ? 剩余分摊数 : 最后一笔分摊数
     */
    @Override
    public ForkQuantityDTO subOdrForkQuantityPayProcess(ForkQuantityDTO forkQuantityDTO) {
        // 1.先对list<...Detail>根据优先级排序
        // 2.按顺序分摊,不能超过剩余的总数量,最后一笔取剩余
        // 3.获取下单时的支付工具进行拆分
    }

四、设计亮点与好处

1、对拆分和服务逻辑做了解耦,将拆分模块化,解决了不同业务分摊的数据一致性问题,提高代码的可维护性可扩展性

2、自适应复杂的业务场景,支持对复杂场景配置和组装,实现新业务新需求时改动小,提高开发效率

3、支持对其他业务提供服务,解决了业务逻辑处理异地处理

相关文章
|
缓存 监控 Linux
C++项目实战-高并发服务器详析(二)
C++项目实战-高并发服务器详析(二)
303 0
|
Linux 调度 C++
C++项目实战-高并发服务器详析(一)
C++项目实战-高并发服务器详析(一)
697 0
|
存储 Java 数据安全/隐私保护
项目实战典型案例15——高并发环境下由于使用全局变量导致数据混乱 高并发环境下对象被大量创建,导致GC并是CPU飙升
项目实战典型案例15——高并发环境下由于使用全局变量导致数据混乱 高并发环境下对象被大量创建,导致GC并是CPU飙升
459 0
项目实战典型案例15——高并发环境下由于使用全局变量导致数据混乱 高并发环境下对象被大量创建,导致GC并是CPU飙升
|
存储 数据采集 JSON
【高并发项目实战】工程模块化与活动会场静态化架构原理解析
活动会场往往聚集着大量流量,千万甚是上亿级别很平常,我们做架构设计的时候,应该前端、后端、网关、配置等等都要考虑进去才是一个合格的架构,本文采取工程模块化与活动会场静态化做架构并讲解其设计原理。
|
存储 canal 缓存
【高并发项目实战】千万级并发的购物车系统设计与代码详解
本文主要介绍redis在千万级系统中设计架构方案,如何在设计上抛弃mysql,主架构设计、缓存一致性方案、大value处理方案和redis限流和故障恢复降级方案设计与代码详解
|
架构师 Java 应用服务中间件
Java 架构师+高并发+性能优化+Spring boot大型分布式项目实战
视频课程内容包含: 高级 Java 架构师包含:Spring boot、Spring cloud、Dubbo、Redis、ActiveMQ、Nginx、Mycat、Spring、MongoDB、ZeroMQ、Git、Nosql、Jvm、Mecached、Netty、Nio、Mina、性能调优、高并发、tomcat 负载均衡、大型电商项目实战、高可用、高可扩展、数据库架构设计、Solr 集群与应用、分布式实战、主从复制、高可用集群等高端视频。
3559 0
|
10月前
|
机器学习/深度学习 算法 机器人
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
418 8
|
10月前
|
机器学习/深度学习 算法 自动驾驶
基于导向滤波的暗通道去雾算法在灰度与彩色图像可见度复原中的研究(Matlab代码实现)
基于导向滤波的暗通道去雾算法在灰度与彩色图像可见度复原中的研究(Matlab代码实现)
473 8
|
10月前
|
机器学习/深度学习 算法 机器人
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
800 0
|
10月前
|
机器学习/深度学习 数据采集 负载均衡
结合多种启发式解码方法的混合多目标进化算法,用于解决带工人约束的混合流水车间调度问题(Matlab代码实现)
结合多种启发式解码方法的混合多目标进化算法,用于解决带工人约束的混合流水车间调度问题(Matlab代码实现)
447 0

热门文章

最新文章