负载均衡深度改造,增加分布式锁,表唯一约束等

This commit is contained in:
2026-02-24 11:17:33 +08:00
parent 8d711dc3a2
commit 148a08a3f1
27 changed files with 891 additions and 182 deletions

View File

@@ -0,0 +1,80 @@
package tech.easyflow.common.cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.Collections;
import java.util.UUID;
import java.util.function.Supplier;
@Component
public class RedisLockExecutor {
private static final Logger log = LoggerFactory.getLogger(RedisLockExecutor.class);
private static final long RETRY_INTERVAL_MILLIS = 50L;
private static final DefaultRedisScript<Long> RELEASE_LOCK_SCRIPT;
static {
RELEASE_LOCK_SCRIPT = new DefaultRedisScript<>();
RELEASE_LOCK_SCRIPT.setScriptText(
"if redis.call('get', KEYS[1]) == ARGV[1] then " +
"return redis.call('del', KEYS[1]) " +
"else return 0 end"
);
RELEASE_LOCK_SCRIPT.setResultType(Long.class);
}
@Autowired
private StringRedisTemplate stringRedisTemplate;
public void executeWithLock(String lockKey, Duration waitTimeout, Duration leaseTimeout, Runnable task) {
executeWithLock(lockKey, waitTimeout, leaseTimeout, () -> {
task.run();
return null;
});
}
public <T> T executeWithLock(String lockKey, Duration waitTimeout, Duration leaseTimeout, Supplier<T> task) {
String lockValue = UUID.randomUUID().toString();
boolean acquired = false;
long deadline = System.nanoTime() + waitTimeout.toNanos();
try {
while (System.nanoTime() <= deadline) {
Boolean success = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, leaseTimeout);
if (Boolean.TRUE.equals(success)) {
acquired = true;
break;
}
Thread.sleep(RETRY_INTERVAL_MILLIS);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IllegalStateException("等待分布式锁被中断lockKey=" + lockKey, e);
}
if (!acquired) {
throw new IllegalStateException("获取分布式锁失败请稍后重试lockKey=" + lockKey);
}
try {
return task.get();
} finally {
releaseLock(lockKey, lockValue);
}
}
private void releaseLock(String lockKey, String lockValue) {
try {
stringRedisTemplate.execute(RELEASE_LOCK_SCRIPT, Collections.singletonList(lockKey), lockValue);
} catch (Exception e) {
log.warn("释放分布式锁失败lockKey={}", lockKey, e);
}
}
}