Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >复杂任务中,流程的解耦设计

复杂任务中,流程的解耦设计

作者头像
知了一笑
发布于 2022-06-14 09:27:14
发布于 2022-06-14 09:27:14
1.3K00
代码可运行
举报
文章被收录于专栏:知了一笑知了一笑
运行总次数:0
代码可运行

复杂流程,得一步异步的来;

一、业务场景

在系统开发的过程中,必然存在耗时极高的动作,是基于请求响应模式无法解决的问题,通常会采用解耦的思维,并基于异步或者事件驱动的方式去调度整个流程的完整执行;

文件任务:在系统解析大文件数据时,在获取任务之后,会异步处理后续文件读写流程;

中间表:执行复杂场景的数据分析时,收集完待分析的对象之后,会并发执行各个维度的采集动作,并依次将数据写入临时的中间表中,方便数据查询动作;

在上述场景中,基于单次请求响应无法执行整个过程,必须对流程分段分步和异步推进,在流程中根据场景去判断,是异步有序驱动,还是异步并发处理,并基于各个节点的执行状态判断动作是否成功。

二、任务管理

复杂任务的执行周期相对偏长,要确保稳定的执行则需要对任务做精细的设计和管理,通常会基于如下几个因素去描述任务:

  • 场景:定义任务的主题场景,便于将多种任务做统一管理和调度,例如:文件、数据、报表等;
  • 计划:对任务做好步骤的拆分,并制定和推进相应的执行计划,例如:有序调度、并发执行等;
  • 状态:针对任务和节点的执行计划,都要提供细节的状态定义,例如:开始/结束,进行中/已完成,成功/失败等;

设计合理的任务结构,以便更高效的管理流程,根据主题场景做任务分类,添加相应的执行计划,根据状态跟踪任务执行过程,并对失败动作进行捕捉和重试;

三、设计思路

1、同步请求响应

服务之间的通信模式一般分为:同步和异步两种;同步是指在请求端发出动作之后,会一直等待响应端完成,或者响应超时导致熔断,即在一次请求调用中耦合所有的处理流程;

服务中大部分的请求都是同步响应模式,可以提高系统的响应速度;但是在分布式中,首先要控制超时熔断的时间,避免在流量高峰期请求堆积,拖垮整个服务;另外对于被大量调用的公共服务,要提高并发的支撑能力,降低对请求链路的性能影响。

2、异步解耦模式

异步模式的最大优点就是实现请求和响应的完全解耦,任务只需要触发一次开始动作,后续的流程就会逐步的推进直到结束;各个服务节点处理逻辑不会受到整个请求链路的耗时限制;

实现异步有多种方式,例如:请求回调、发布订阅、Broker代理等;在之前异步章节中有详细描述,这里不再赘述;异步消除了服务节点之间的依赖关系,但是也同样提高了流程的复杂性;

3、事件驱动设计

事件驱动是一个抽象的概念,即通过事件的方式实现多个服务间的协同,驱动整个流程的处理逻辑;在业务层面是一种设计思想,在技术层面通常采用发布订阅的方式,同样也可以消除服务间的强依赖关系;

事件和异步在模式上很类似,事件驱动在设计上更加精细,例如在订单场景中:将订单的状态变化作为一个事件,服务间通过消息传递的方式,依次处理库存服务、物流服务等;由于事件携带了一定的业务信息和状态,流程解耦更加彻底的同时复杂度也会更高。

四、实践总结

1、结构设计

在结构设计中围绕任务、节点、数据三个核心要素,以确保对任务的执行过程有完整的跟踪和管理,要实现对任务的节点及相关的操作,具备执行重试或者直接取消撤回的控制;

状态管理是一项很复杂的工作,要衡量任务中各个状态标识是否合理,就要实时监控状态的变化,并且基于各种极端情况去验证流程,例如:重试设计、任务取消、任务暂停。

2、高并发管理

任务型的场景加上复杂的管理流程,执行时间自然也很长,如果场景中涉及到大文件的解析、或者数据调度,自然会引入任务分割与并发执行的机制;

比较常用的思路:根据任务调度的集群数,对数据核心编号进行哈希计算,可以采用取模和分段两种算法,然后基于多线程的方式并发处理各自服务内的分管任务。

3、管理模型

不管是观察者模式,或者发布订阅模型,又或者说事件驱动设计,都可以理解为生产/消费的关系模型,围绕生产、存储、消费三个节点做管理;

  • 生产端:负责创建具体的消息主体,在总线模式中,通常将消息进行入库存储,然后再执行队列推送,并跟踪该过程的状态变化,保证库和队列的一致性;
  • 消息体:描述动作的发布方和消费方,关键的状态信息变化,唯一标识和创建时间及版本,其余则根据场景需要定义即可;
  • 消费端:在消费时要关注的核心问题即失败重试,要避免重试机制引起数据不一致的问题,可以对消费进行加锁或者消息状态校验,以实现幂等的效果;
  • 存储端:通常采用数据库和消息中间件双存储的模式,并且需要保证二者动作的同时成功或者失败,顺序为先入库再执行队列推送;

整个模型在设计思路上比较合理,但是架构的复杂性也变的很高,比如数据一致性问题、状态机制、事务、幂等性、流程中断等;整个链路需要详细的追踪记录并且可视化管理,开发补偿动作的接口,用来及时解决可能出现的突发问题。

4、组件案例

Spring框架本身就极具复杂度,这里单看事件模型的设计,包含三个核心角色:事件、发布、监听;与观察者设计模式在理念上相同;

事件:ApplicationEvent基础抽象类继承自JDK中EventObject类,具体事件要继承该类;source事件源,timestamp发生的系统时间;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class OrderState {
    // 基础要素
    private Integer eventId ;
    private String version ;
    private Long createTime ;

    // 消息定位
    private String source ;
    private String target ;

    // 状态变化
    private Integer orderId ;
    private Integer stateFrom ;
    private Integer stateTo ;
}
public class OrderStateEvent extends ApplicationEvent {
    public OrderStateEvent (OrderState orderState){
        super(orderState);
    }
}

发布者:Spring定义的顶级接口ApplicationEventPublisher,提供事件发布的能力;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Service
public class EventService implements ApplicationContextAware, ApplicationEventPublisherAware {
    private ApplicationEventPublisher applicationEventPublisher;
    
    public void changeState (Integer orderId,Integer stateFrom,Integer stateTo){
        OrderState orderState = new OrderState() ;
        OrderStateEvent orderStateEvent = new OrderStateEvent(orderState) ;
        logger.info(Thread.currentThread().getName()+";"+orderStateEvent);
        applicationEventPublisher.publishEvent(orderStateEvent);
    }
}

监听者:实现JDK中顶级接口EventListener,Spring扩展了多种事件监听器,以实现各种场景的需求,例如:有序无序、同步异步等;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Component
public class OrderStateListener implements ApplicationListener<OrderStateEvent> {
    private static final Logger logger = LoggerFactory.getLogger(OrderStateListener.class) ;

    @Async
    @Override
    public void onApplicationEvent(OrderStateEvent orderStateEvent) {
        logger.info(Thread.currentThread().getName()+";"+orderStateEvent);
    }
}

五、参考源码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
应用仓库:
https://gitee.com/cicadasmile/middle-ware-parent

编程文档:
https://gitee.com/cicadasmile/butte-java-note
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 知了一笑 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
一文读懂内部组件解耦神器 Spring Event(Spring 事件)
👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.
Lorin 洛林
2023/11/03
3.1K0
一文读懂内部组件解耦神器 Spring Event(Spring 事件)
微服务架构下如何解耦,对于已经紧耦合下如何重构?
今天准备谈下微服务架构下各个微服务间如何解耦,以及对于已经紧耦合的微服务如何进行重构。在谈这个内容前,可以先看下我前两天发布的微服务模块和粒度如何划分才更加合理的一篇文章,这篇文章对于微服务拆分有比较详细的描述。
xcbeyond
2020/11/04
1.5K1
微服务架构下如何解耦,对于已经紧耦合下如何重构?
架构设计 | 异步处理流程,多种实现模式详解
异步处理不用阻塞当前线程来等待处理完成,而是允许后续操作,直至其它线程将处理完成,并回调通知此线程。
知了一笑
2020/06/10
1.7K0
架构设计 | 异步处理流程,多种实现模式详解
设计模式之订阅发布模式
订阅发布模式(Publish-Subscribe Pattern)是一种行之有效的解耦框架与业务逻辑的方式,也是一种常见的观察者设计模式,它被广泛应用于事件驱动架构中。
wayn
2023/05/27
7880
设计模式之订阅发布模式
Spring Event 业务解耦神器,刷爆了
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/07/26
7390
Spring Event 业务解耦神器,刷爆了
浅析Spring中的事件驱动机制
今天来简单地聊聊事件驱动,其实写这篇文章挺令我挺苦恼的,因为事件驱动这个名词,我没有找到很好的定性解释,担心自己的表述有误,而说到事件驱动可能立刻联想到如此众多的概念:观察者模式,发布订阅模式,消息队列MQ,消息驱动,事件,EventSourcing...为了不产生歧义,笔者把自己所了解的这些模棱两可的概念都列了出来,再开始今天的分享。 在设计模式中,观察者模式可以算得上是一个非常经典的行为型设计模式,猫叫了,主人醒了,老鼠跑了,这一经典的例子,是事件驱动模型在设计层面的体现。 另一模式,发布订阅模式往往
kirito-moe
2018/04/27
2K0
浅析Spring中的事件驱动机制
构建高效稳定的并发处理系统:从理论到实战的全面优化指南
在如今的互联网时代,应用程序需要处理大量并发用户请求。无论是电子商务平台上的秒杀活动,还是社交媒体的实时消息推送,系统的高并发处理能力直接影响着用户体验和企业的竞争力。在这种情况下,如何高效地管理线程资源,成为了每个开发者需要面对的重要课题。
繁依Fanyi
2024/08/14
6620
浅析 Spring 中的事件驱动机制
今天来简单地聊聊事件驱动,其实写这篇文章挺令我挺苦恼的,因为事件驱动这个名词,我没有找到很好的定性解释,担心自己的表述有误,而说到事件驱动可能立刻联想到如此众多的概念:观察者模式,发布订阅模式,消息队列MQ,消息驱动,事件,EventSourcing…为了不产生歧义,笔者把自己所了解的这些模棱两可的概念都列了出来,再开始今天的分享。
三哥
2018/07/31
1.2K0
浅析 Spring 中的事件驱动机制
Spring发布-订阅模式:解耦与异步通信的高效实现
Spring框架通过发布订阅模式为组件间通信提供了高效且松散耦合的解决方案,提升了系统的灵活性和扩展性。本文将探讨该模式的原理、实现、应用场景及其优势与挑战。
Java微观世界
2025/01/20
2100
spring的事件驱动有时候比消息队列好用
在现代开发中,异步处理越来越受到青睐。常见方案是通过消息队列实现异步通信,但Spring Boot的事件驱动模型提供了一种更轻量级的选择。本文将带你了解事件驱动的基本原理及其应用场景。
一只牛博
2025/05/30
1020
spring的事件驱动有时候比消息队列好用
根据实际开发经验(订单管理系统),谈谈多线程开发的好处
多线程开发在订单管理系统中提高了系统的并发处理能力,使得系统更具有弹性和响应性。通过合理设计和使用多线程,可以提高代码的复用性,减少重复工作,使得系统更易于扩展和维护。
人不走空
2024/02/20
3170
DDD落地之事件驱动模型
周末的时候写了一文带你落地DDD,发现大家对于新的领域与知识都挺感兴趣的。后面将会出几篇DDD系列文章给大家介绍mvc迁移DDD实际要做的一些步骤。
柏炎
2022/08/23
1.1K0
DDD落地之事件驱动模型
探索 RocketMQ:企业级消息中间件的选择与应用
RocketMQ 是一个高性能、高可靠、可扩展的分布式消息中间件,它是由阿里巴巴开发并贡献给 Apache 软件基金会的一个开源项目。RocketMQ 主要用于处理大规模、高吞吐量、低延迟的消息传递,它是一个轻量级的、功能强大的消息队列系统,广泛应用于金融、电商、日志系统、数据分析等领域。
用户7954602
2024/11/23
2410
探索 RocketMQ:企业级消息中间件的选择与应用
持续事务管理过程中的事件驱动
系统间的通讯方式一般可分为同步通信和异步通信两种,我们可以将将同步通讯理解为打电话,需要实时响应,而异步通信则可理解为发送短信,不需要马上回复。我们往往会在面对超高吐吞量的场景下采取异步通讯,因为这就好比一个人不可能同时接打很多电话,但是他可以同时接收很多的电子邮件一样。
栗筝i
2023/03/08
6320
持续事务管理过程中的事件驱动
基于领域事件实现微服务解耦
除了命令和操作等业务行为,还有一种非常重要的事件,这种事件通常会导致进一步的业务操作,在DDD(Domain Driven Design,领域驱动设计)中,这种事件叫做 领域事件。
王小明_HIT
2023/03/01
4470
基于领域事件实现微服务解耦
高性能IO编程设计
? 首先,在讲述高性能IO编程设计的时候,我们先思考一下何为“高性能”呢,如果自己来设计一个web体系服务,选择BIO还是NIO的编程方式呢?其次,我们可以了解下构建一个web体系服务中,为了能够支撑
小坤探游架构笔记
2020/04/07
1.2K0
分布式任务调度:你知道和不知道的事
导语 对于定时任务大家应该都不会陌生,从骨灰级别的Crontab到Spring Task,从QuartZ到xxl-job,随着业务场景越来越多样复杂,定时任务框架也在不断的升级进化。 那么今天就来跟大家从以下三个方面聊一聊分布式任务调度:从单机定时任务到分布式任务调度平台的演进过程、腾讯云分布式任务调度平台TCT是如何应运而生的、TCT具体落地案例情况和解决了哪些核心问题。 作者简介  崔凯 腾讯云 CSIG 微服务产品中心产品架构师 多年分布式、高并发电子商务系统的研发、系统架构设计经验,擅长主流微服务
腾讯云中间件团队
2022/03/10
2.2K0
图解7种分布式事务模型(一文带你掌握分布式事务)
Hello 我是方才,10人研发leader、4年团队管理&架构经验。文末,方才送你一份25年最新的架构师备考资料,记得领取哟!
方才编程_公众号同名
2025/04/02
4340
图解7种分布式事务模型(一文带你掌握分布式事务)
[源码解析] 并行分布式框架 Celery 之架构 (2)
Celery是一个简单、灵活且可靠的,处理大量消息的分布式系统,专注于实时处理的异步任务队列,同时也支持任务调度。
罗西的思考
2021/04/01
9600
【Spring云原生系列】SpringBoot+Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合!
随着云计算、微服务和大数据技术的快速发展,构建可扩展、高性能和弹性的应用程序变得越来越重要。为了满足这些要求,许多开发人员转向了事件驱动架构,它允许应用程序通过基于事件的方式相互通信,从而提高了系统的响应速度和伸缩性。在这个背景下,Spring Cloud Stream应运而生,它是一个用于构建基于事件驱动的微服务应用程序的框架,可以与现有的消息中间件(如Apache Kafka和RabbitMQ)无缝集成。
苏泽
2024/03/10
3980
【Spring云原生系列】SpringBoot+Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合!
推荐阅读
相关推荐
一文读懂内部组件解耦神器 Spring Event(Spring 事件)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档