该分布式幂等组件基于 Spring AOP 和 Redis 实现,通过注解声明式配置,提供灵活、高性能的接口幂等性保障。支持快速失败与阻塞等待两种模式,集成自定义策略扩展能力,适用于springboot项目分布式场景下的重复请求拦截与处理。
代码已上传github,欢迎star: 传送门
@Idempotent
注解标记需幂等控制的方法,支持参数动态配置。 NULL
)、抛出异常( EXCEPTION
)、返回历史结果( PREVIOUS
)。 failFast=true
)或阻塞等待锁( failFast=false
)。 columns
参数指定幂等键生成规则,支持 EL 表达式动态提取参数。 IdempotentAspect
拦截被 @Idempotent
注解标记的方法。 uid
或 类名+方法名
构建唯一键,结合参数生成 Redis Key。 IdempotentContext
。 核心代码:
@Around("@annotation(anno)")
public final Object proceed(ProceedingJoinPoint joinPoint, Idempotent anno) throws Throwable {
// 所有的参数值的数组
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
// 幂等增强 委托给IdempotentExecutor
Object retObj = executor.execute(new IdempotentCallback
IdempotentExecutor
获取 Redisson 锁,确保并发安全。
PersistProcessor
检查 Redis 中是否存在历史记录,避免重复提交。 核心代码:
public final R execute(IdempotentCallback callback) throws Throwable {
IdempotentContext context = callback.initContext();
String uid = context.getUid();
if (StringUtils.isBlank(uid)) {
throw new Exception("幂等组件: uid不能为空");
}
List param = context.getIdemParam();
if (CollectionUtils.isEmpty(param)) {
throw new Exception("幂等组件: idemParam不能为空");
}
RLock lock = client.getLock(buildLock(uid, param));
return context.isFailFast() ? doFast(callback, context, lock) : doLazy(callback, context, lock);
}
private R doLazy(IdempotentCallback callback, IdempotentContext context, RLock lock) throws Throwable {
lock.lock();
try {
IdempotentResult result = context.getIdemHandler().handle(context);
if (result.isFlag()) {
//执行
R r = callback.execute();
//缓存结果,自定义策略不缓存
processor.persist(context.setResult(r));
return r;
}
return context.setResult(result.getResult()).getRespHandler().handle(context);
} finally {
lock.unlock();
}
}
private R doFast(IdempotentCallback callback, IdempotentContext context, RLock lock) throws Throwable {
if (lock.tryLock()) {
try {
//获取到锁,执行逻辑
IdempotentResult result = context.getIdemHandler().handle(context);
if (result.isFlag()) {
//执行
R r = callback.execute();
//缓存结果,自定义策略不缓存
processor.persist(context.setResult(r));
return r;
}
} finally {
lock.unlock();
}
}
return context.getRespHandler().handle(context);
}
<dependency>
<groupId>com.shemuelgroupId>
<artifactId>idempotent-boot-starterartifactId>
<version>1.0.0version>
dependency>
idempotent:
enable: true
env: prod
redis:
host: 127.0.0.1
port: 6379
password: redis-pass
@Idempotent(
uid = "order.create",
columns = {"#userId", "#orderId"}, // 动态提取参数
failFast = true,
duration = 10,
custom = @Strategy(
idemStrategy = IdemStrategy.DEFAULT,
respStrategy = RespStrategy.EXCEPTION
)
)
public Order createOrder(Long userId, String orderId) {
// 业务逻辑
}
IdemHandler
:覆盖 doHandle
方法定义自定义幂等逻辑。 RespHandler
:覆盖 doHandle
方法定义自定义响应逻辑。 IdemHandlerFactory
或 RespHandlerFactory
注册 Bean。 IdempotentExecutor
封装执行流程,子流程(如锁获取、持久化)通过回调接口 IdempotentCallback
实现。 IdemStrategy
和 RespStrategy
定义多套处理策略,支持运行时动态切换。 IdemHandlerFactory
和 RespHandlerFactory
集中管理处理器实例,解耦创建与使用逻辑。 该组件通过 注解驱动 + 分布式锁 + 策略扩展 的设计,实现了轻量级、高可用的幂等控制。开发者无需修改业务代码即可集成,同时支持灵活扩展,适用于电商、金融等高并发场景,有效保障系统数据一致性。
代码已上传github, 欢迎star; https://github.com/ShemuelDeng/distributed-idempotent
欢迎关注gzh:加瓦点灯, 每天推送干货知识!