基于Disruptor的重试队列实现
import com.lmax.disruptor.*;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import java.util.concurrent.Executors;
public class RetryQueueWithDisruptor {
// 事件类
static class RetryEvent {
private Runnable task;
private int retryCount;
// getters and setters
}
// 事件工厂
static class RetryEventFactory implements EventFactory<RetryEvent> {
@Override
public RetryEvent newInstance() {
return new RetryEvent();
}
}
// 事件处理器
static class RetryEventHandler implements EventHandler<RetryEvent> {
private final int maxRetries;
public RetryEventHandler(int maxRetries) {
this.maxRetries = maxRetries;
}
@Override
public void onEvent(RetryEvent event, long sequence, boolean endOfBatch) {
try {
event.getTask().run();
} catch (Exception e) {
if (event.getRetryCount() < maxRetries) {
event.setRetryCount(event.getRetryCount() + 1);
// 计算退避时间
long delay = calculateBackoff(event.getRetryCount());
// 实际应用中应使用定时器重新发布事件
try {
Thread.sleep(delay);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
// 重新发布事件进行重试
disruptor.publishEvent((retryEvent, seq) -> {
retryEvent.setTask(event.getTask());
retryEvent.setRetryCount(event.getRetryCount());
});
} else {
// 达到最大重试次数,记录失败
System.err.println("任务重试失败: " + e.getMessage());
}
}
}
private long calculateBackoff(int retryCount) {
return (long) Math.min(1000 * Math.pow(2, retryCount), 60000);
}
}
private static Disruptor<RetryEvent> disruptor;
public static void start(int bufferSize, int maxRetries) {
RetryEventFactory factory = new RetryEventFactory();
disruptor = new Disruptor<>(
factory,
bufferSize,
Executors.defaultThreadFactory(),
ProducerType.MULTI,
new BlockingWaitStrategy()
);
disruptor.handleEventsWith(new RetryEventHandler(maxRetries));
disruptor.start();
}
public static void submitTask(Runnable task) {
disruptor.publishEvent((event, sequence) -> {
event.setTask(task);
event.setRetryCount(0);
});
}
}
基于LinkedBlockingQueue的重试队列实现
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class RetryQueueWithBlockingQueue {
private final BlockingQueue<Runnable> queue;
private final ExecutorService executor;
private final int maxRetries;
public RetryQueueWithBlockingQueue(int queueSize, int threadPoolSize, int maxRetries) {
this.queue = new LinkedBlockingQueue<>(queueSize);
this.executor = Executors.newFixedThreadPool(threadPoolSize);
this.maxRetries = maxRetries;
startConsumers();
}
private void startConsumers() {
for (int i = 0; i < executor.getMaximumPoolSize(); i++) {
executor.submit(() -> {
while (!Thread.currentThread().isInterrupted()) {
try {
Runnable task = queue.take();
executeWithRetry(task);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
}
}
public boolean submit(Runnable task) {
return queue.offer(task);
}
private void executeWithRetry(Runnable task) {
AtomicInteger retryCount = new AtomicInteger(0);
while (retryCount.get() < maxRetries) {
try {
task.run();
return;
} catch (Exception e) {
int count = retryCount.incrementAndGet();
if (count >= maxRetries) {
System.err.println("任务重试失败: " + e.getMessage());
return;
}
long delay = calculateBackoff(count);
try {
Thread.sleep(delay);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
return;
}
}
}
}
private long calculateBackoff(int retryCount) {
return (long) Math.min(1000 * Math.pow(2, retryCount), 60000);
}
public void shutdown() {
executor.shutdownNow();
}
}