Design and Implementation of a Generic Asynchronous Processing SDK
This article introduces a generic asynchronous processing SDK for Java Spring applications, covering its purpose, advantages, underlying principles, component choices such as Kafka, XXL‑Job, MySQL, design patterns, database schema, configuration via Apollo, usage instructions, safety considerations, and provides code examples and a GitHub repository link.
Good system design must follow the open‑closed principle; as business evolves, core code changes increase error risk. Most new features extend existing functionality, requiring both performance and quality, so asynchronous thread pools are often used, albeit introducing uncertainty.
Therefore, a generic asynchronous processing SDK was designed to simplify various async tasks.
Purpose : Ensure method execution without blocking the main flow and guarantee data persistence for eventual consistency.
Advantages :
Non‑intrusive design with independent database, scheduled tasks, message queue, and UI (single sign‑on).
Leverages Spring transaction event mechanism; async strategy failures do not affect business logic.
If a method runs within a transaction, the event is processed after commit or rollback.
Fallback execution is provided unless the database, message queue, or method itself fails.
Principle : After container initialization, all methods annotated with @AsyncExec are cached. At runtime, an AOP aspect publishes an event, and a transaction event listener processes the asynchronous execution strategy.
Example listener annotation:
@TransactionalEventListener(fallbackExecution = true, phase = TransactionPhase.AFTER_COMPLETION)Key components:
Kafka message queue
XXL‑Job scheduled tasks
MySQL database
Spring AOP
Vue front‑end UI
Design Patterns :
Strategy
Template Method
Dynamic Proxy
Database scripts (simplified):
CREATE TABLE `async_req` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`application_name` varchar(100) NOT NULL DEFAULT '' COMMENT '应用名称',
`sign` varchar(50) NOT NULL DEFAULT '' COMMENT '方法签名',
`class_name` varchar(200) NOT NULL DEFAULT '' COMMENT '全路径类名称',
`method_name` varchar(100) NOT NULL DEFAULT '' COMMENT '方法名称',
`async_type` varchar(50) NOT NULL DEFAULT '' COMMENT '异步策略类型',
`exec_status` tinyint NOT NULL DEFAULT '0' COMMENT '执行状态 0:初始化 1:执行失败 2:执行成功',
`exec_count` int NOT NULL DEFAULT '0' COMMENT '执行次数',
`param_json` longtext COMMENT '请求参数',
`remark` varchar(200) NOT NULL DEFAULT '' COMMENT '业务描述',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_applocation_name` (`application_name`),
KEY `idx_exec_status` (`exec_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='异步处理请求';
CREATE TABLE `async_log` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`async_id` bigint NOT NULL COMMENT '异步请求ID',
`error_data` longtext COMMENT '执行错误信息',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_async_id` (`async_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='异步处理日志';Async Strategy Flowchart (illustrated in the original article).
Security Levels and Execution Status are visualized with diagrams in the source.
Apollo Configuration Example :
# Switch (default off)
async.enabled=true
# Application name
spring.application.name=xxx
# DataSource (Druid)
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/fc_async?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true
spring.datasource.username=user
spring.datasource.password=xxxx
spring.datasource.filters=config
spring.datasource.connectionProperties=config.decrypt=true;config.decrypt.key=yyy
# Thread pool settings
async.executor.thread.corePoolSize=10
async.executor.thread.maxPoolSize=50
async.executor.thread.queueCapacity=10000
async.executor.thread.keepAliveSeconds=600
# Delete record after success
async.exec.deleted=true
# Topic prefix (default application name)
async.topic=${spring.application.name}
# Retry settings
async.exec.count=5
async.retry.limit=100
async.comp.limit=100
# Login interception (default false)
async.login=falseUsage :
Enable async: scm.async.enabled=true Add @AsyncExec(...) annotation to Spring‑proxied methods.
Access manual processing UI at http://localhost:8004/async/index.html.
Notes :
Ensure the application name is correctly set (e.g., spring.application.name).
Queue name defaults to ${async.topic:${spring.application.name}_async_queue; can be overridden with async.topic=xxx.
Business logic should be idempotent.
One queue per application is recommended.
Scheduled tasks handle retry (every 2 min) and compensation (hourly) for failed async requests.
Effect Demonstration (image in original article).
Source code is available at https://github.com/xiongyanokok/fc-async.git .
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
IT Architects Alliance
Discussion and exchange on system, internet, large‑scale distributed, high‑availability, and high‑performance architectures, as well as big data, machine learning, AI, and architecture adjustments with internet technologies. Includes real‑world large‑scale architecture case studies. Open to architects who have ideas and enjoy sharing.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
