开发者社区> 小明的Java问道之路> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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

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

前言

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

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

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

本文导读

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

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

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

image

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

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

image

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

二、交易模型设计原理

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

1、数据模块

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

image

2、事件模块 

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

image

3、服务模块

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

image

4、算法模块

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

image

5、整体设计

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

image

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

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、支持对其他业务提供服务,解决了业务逻辑处理异地处理

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Vue.js 依赖收集
Vue.js 依赖收集
51 0
自己开发的一个SAP CRM订单统计工具
自己开发的一个SAP CRM订单统计工具
51 0
Java Spring Boot2.0实战MongoDB数据库(移动架构与MongoDB面试题)
MongoDB面试题,NoSQL排名第一!BAT等一线互联网名企面试必备,本课程讲解如何使用最新的Java Spring Data 2.0 实战MongoDB数据库,以及底层API的实现源码。
2425 0
springCloud Finchley 实战入门(基于springBoot 2.0.3)【四 Ribbon 服务容错保护】
spring Cloud Ribbon Ribbon是一个基于HTTP和TCP协议的客户端负载均衡工具,他也是基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们很容易的将面向服务的REST模板请求自动转换成客户端负载均衡的调用。
1219 0
JavaWeb项目架构之NFS文件服务器
NFS简介 NFS(Network File System)即网络文件系统。 主要功能:通过网络(局域网)让不同的主机系统之间可以共享文件或目录。 主要用途:NFS网络文件系统一般被用来存储共享视频,图片,附件等静态资源文件。
5669 0
JAVAWEB贵美网上商城完整项目源码(SSH2)
JAVAWEB贵美网上商城完整项目源码(SSH2) 贵美网上商城原是北大青鸟的一个内部项目,项目采用 struts2+spring4+hibernate4+mysql等技术实现,数据库连接池采用c3p0的方式。 贵美商城包括前后台。前台采用绚丽的jquer+jquery.validate实现效果显示,实现注册登录 浏览商品详情 加入购物车等功能。后台采用easyui实现管理员登录
2986 0
自己开发给自己用的个人知识管理工具【脑细胞】,源码提供
源起: 市面上流行的两大知识管理工具,有道云笔记和为知笔记 都是通过层级结构的目录(树状目录)来管理知识的; 我觉得这是不符合记忆规律的, 人脑不是靠树状目录来管理知识的,而是靠关系来管理知识的! 为了强化体现知识的关系 我对为这个工具做了一套标签体系, ...
1071 0
+关注
小明的Java问道之路
某大型金融企业后端高级工程师、Java领域优质创作者、云享专家,专注于研究计算机底层/Java/架构/设计模式/算法
71
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载