news 2026/5/15 18:26:32

一套万能通用的异步处理方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一套万能通用的异步处理方案

前言

良好的系统设计必须要做到开闭原则,随着业务的不断迭代更新,核心代码也会被不断改动,出错的概率也会大大增加。但是大部分增加的功能都是在扩展原有的功能,既要保证性能又要保证质量,我们往往都会使用异步线程池来处理,然而却增加了很多不确定性因素。由此我设计了一套通用的异步处理 SDK,可以很轻松的实现各种异步处理!

目的

通过异步处理不仅能够保证方法能够得到有效的执行而且不影响主流程

更重要的是各种兜底方法保证数据不丢失,从而达到最终一致性

优点

无侵入设计,独立数据库,独立定时任务,独立消息队列,独立人工执行界面(统一登录认证)

使用 spring 事务事件机制,即使异步策略解析失败也不会影响业务

如果你的方法正在运行事务,会等事务提交后或回滚后再处理事件

就算事务提交了,异步策略解析失败了,我们还有兜底方案执行(除非数据库有问题,消息队列有问题,方法有 bug)

原理

容器初始化 bean 完成后遍历所有方法,把有@AsyncExec注解的方法缓存起来

方法运行时通过 AOP 切面发布事件

事务事件监听处理异步执行策略

@TransactionalEventListener(fallbackExecution = true, phase = TransactionPhase.AFTER_COMPLETION)
  • fallbackExecution=true没有事务正在运行,依然处理事件

  • TransactionPhase.AFTER_COMPLETION事务提交后和事务回滚后都处理事件

组件

  • kafka 消息队列

  • xxl job 定时任务

  • mysql 数据库

  • spring 切面

  • vue 界面

设计模式

  • 策略

  • 模板方法

  • 动态代理

流程图

数据库脚本

CREATETABLE`async_scene` ( `id`bigintNOTNULL AUTO_INCREMENT COMMENT'主键ID', `application_name`varchar(100) NOTNULLDEFAULT''COMMENT'应用名称', `method_sign`varchar(50) NOTNULLDEFAULT''COMMENT'方法签名', `scene_name`varchar(200) NOTNULLDEFAULT''COMMENT'业务场景描述', `async_type`varchar(50) NOTNULLDEFAULT''COMMENT'异步策略类型', `queue_name`varchar(200) NOTNULLDEFAULT''COMMENT'队列名称', `theme_value`varchar(100) NOTNULLDEFAULT''COMMENT'消费主题', `exec_count`intNOTNULLDEFAULT'0'COMMENT'失败重试次数', `exec_deleted`intNOTNULLDEFAULT'0'COMMENT'执行后是否删除', `async_version`varchar(50) NOTNULLDEFAULT''COMMENT'组件版本号', `create_time` datetime NOTNULLDEFAULTCURRENT_TIMESTAMPCOMMENT'创建时间', `update_time` datetime NOTNULLDEFAULTCURRENT_TIMESTAMPCOMMENT'更新时间', `cdc_crt_time` datetime NOTNULLDEFAULTCURRENT_TIMESTAMPCOMMENT'记录新增时间', `cdc_upd_time` datetime NOTNULLDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMPCOMMENT'记录修改时间', PRIMARY KEY (`id`) USING BTREE, UNIQUEKEY`uk_application_sign` (`application_name`,`method_sign`) USING BTREE, KEY`idx_cdc_upd_time` (`cdc_upd_time`) ) ENGINE=InnoDBCOMMENT='异步场景表'; CREATETABLE`async_req` ( `id`bigintNOTNULL AUTO_INCREMENT COMMENT'主键ID', `application_name`varchar(100) NOTNULLDEFAULT''COMMENT'应用名称', `sign`varchar(50) NOTNULLDEFAULT''COMMENT'方法签名', `class_name`varchar(200) NOTNULLDEFAULT''COMMENT'全路径类名称', `method_name`varchar(100) NOTNULLDEFAULT''COMMENT'方法名称', `async_type`varchar(50) NOTNULLDEFAULT''COMMENT'异步策略类型', `exec_status`tinyintNOTNULLDEFAULT'0'COMMENT'执行状态 0:初始化 1:执行失败 2:执行成功', `exec_count`intNOTNULLDEFAULT'0'COMMENT'执行次数', `param_json` longtext COMMENT'请求参数', `remark`varchar(200) NOTNULLDEFAULT''COMMENT'业务描述', `create_time` datetime NOTNULLDEFAULTCURRENT_TIMESTAMPCOMMENT'创建时间', `update_time` datetime NOTNULLDEFAULTCURRENT_TIMESTAMPCOMMENT'更新时间', PRIMARY KEY (`id`) USING BTREE, KEY`idx_applocation_name` (`application_name`) USING BTREE, KEY`idx_exec_status` (`exec_status`) USING BTREE ) ENGINE=InnoDBDEFAULTCHARSET=utf8mb4 COMMENT='异步处理请求'; CREATETABLE`async_log` ( `id`bigintNOTNULL AUTO_INCREMENT COMMENT'主键ID', `async_id`bigintNOTNULLDEFAULT'0'COMMENT'异步请求ID', `error_data` longtext COMMENT'执行错误信息', `create_time` datetime NOTNULLDEFAULTCURRENT_TIMESTAMPCOMMENT'创建时间', PRIMARY KEY (`id`) USING BTREE, KEY`idx_async_id` (`async_id`) USING BTREE ) ENGINE=InnoDBDEFAULTCHARSET=utf8mb4 COMMENT='异步处理日志';

异步策略

安全级别

执行状态

流程图

apollo 配置

# 开关:默认关闭 async.enabled=true # 应用名称 spring.application.name=xxx # 数据源 druid async.datasource.driver-class-name=com.mysql.jdbc.Driver async.datasource.url=jdbc:mysql://127.0.0.1:3306/fc_async?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true async.datasource.username=user async.datasource.password=xxxx async.datasource.filters=config async.datasource.connectionProperties=config.decrypt=true;config.decrypt.key=yyy #静态地址 spring.resources.add-mappings=true spring.resources.static-locations=classpath:/static/ # 以下配置都有默认值 # 核心线程数 async.executor.thread.corePoolSize=10 # 最大线程数 async.executor.thread.maxPoolSize=50 # 队列容量 async.executor.thread.queueCapacity=10000 # 活跃时间 async.executor.thread.keepAliveSeconds=600 # 执行成功是否删除记录:默认删除 async.exec.deleted=true # 自定义队列名称前缀:默认应用名称 async.topic=${spring.application.name} # 重试执行次数:默认5次 async.exec.count=5 # 重试最大查询数量 async.retry.limit=100 # 补偿最大查询数量 async.comp.limit=100 # 登录拦截:默认false async.login=false

用法

1,异步开关
scm.async.enabled=true
2,在需要异步执行的方法加注解 (必须是spring代理方法)
@AsyncExec(type = AsyncExecEnum.SAVE_ASYNC, remark = "数据字典")
3,人工处理地址

http://localhost:8004/async/index.html

注意

1,应用名称
spring.application.name
2,队列名称
${async.topic:${spring.application.name}}_async_queue
3,自己业务要做幂等
4,一个应用公用一个队列

自产自消

5,定时任务
  • 异步重试定时任务(2分钟重试一次,可配置重试次数)

  • 异步补偿定时任务(一小时补偿一次,创建时间在一小时之前的)

效果展示

GitHub 地址

https://github.com/xiongyanokok/fc-async

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/4 17:10:59

AI供应链惊魂!OpenClaw 341个恶意技能,正在收割全球用户数据

当AI代理工具从“便捷辅助”升级为“日常刚需”,其生态供应链已成为黑产团伙的新猎场。近期OpenClaw平台爆发的ClawHavoc大规模投毒事件,341个恶意技能潜伏于官方市场,恶意占比超11.9%,刷新了AI插件生态供应链攻击的规模纪录。这不…

作者头像 李华
网站建设 2026/5/11 11:38:08

云计算如何助力企业实现安全高效的规模化发展!

云计算是企业实现安全高效规模化的核心引擎,它通过提供可扩展、灵活且智能的基础设施与服务,从根本上改变了企业增长的方式。以下是其关键作用的详细解析:一、实现“高效规模化”的核心能力弹性伸缩,告别资源瓶颈按需供应&#xf…

作者头像 李华
网站建设 2026/5/5 2:29:00

什么是机器学习?—— 用 “买西瓜” 讲透核心逻辑

什么是机器学习?—— 用 “买西瓜” 讲透核心逻辑 快速导读 难度:入门位置:第 1 篇读完可接:第 2 篇《机器学习基本术语大拆解 —— 用西瓜数据集逐个对应》 文章目录什么是机器学习?—— 用 “买西瓜” 讲透核心逻…

作者头像 李华
网站建设 2026/5/14 17:20:19

Cosmos-Reason1-7B快速部署:Docker镜像免配置启动本地推理服务

Cosmos-Reason1-7B快速部署:Docker镜像免配置启动本地推理服务 一句话总结:无需复杂配置,一条命令启动专业级本地推理服务,让AI帮你解决逻辑推理、数学计算和编程问题。 1. 为什么选择Cosmos-Reason1-7B? 如果你经常需…

作者头像 李华
网站建设 2026/5/14 8:06:05

UI-TARS-desktop入门必看:零基础搭建AI开发环境

UI-TARS-desktop入门必看:零基础搭建AI开发环境 1. UI-TARS-desktop是什么?为什么选择它? 如果你正在寻找一个能在自己电脑上运行的AI助手,既能理解你的指令,又能帮你完成各种实际任务,那么UI-TARS-deskt…

作者头像 李华
网站建设 2026/5/12 14:21:37

校验日期格式:正则表达式

// 不允许空字符串,使用分支(|) Pattern(regexp "^\\d{4}-\\d{2}-\\d{2}$", message "日期格式必须为yyyy-MM-dd") // 允许空字符串,使用分支(|) Pattern(regexp "^\\d{4}-\\d{2}-\\d{2}$|^$", message "日期格式…

作者头像 李华