Why Fast‑Retry Beats Spring‑Retry for Massive Asynchronous Retries
Fast‑Retry is a high‑performance, multi‑task asynchronous retry framework for Java that dramatically outperforms traditional synchronous retry libraries like Spring‑Retry and Guava‑Retry, especially when handling millions of tasks, by leveraging non‑blocking execution, customizable strategies, and seamless Spring integration.
Preface
Assume your system has one million users and you need to poll each user's identity information. Using synchronous retry frameworks such as Spring‑Retry or Guava‑Retry would make this impossible, even with many machines and threads, whereas Fast‑Retry is built for this scenario.
Fast‑Retry
A high‑performance multi‑task retry framework that supports asynchronous retries for millions of tasks, offering both programmatic and annotation‑based usage as well as custom result‑based retry logic.
What is this?
Unlike mainstream synchronous retry frameworks like Spring‑Retry and Guava‑Retry, Fast‑Retry is an asynchronous retry framework that supports async tasks, timeout waiting, and callbacks. Synchronous frameworks block threads for each retry, causing throughput to drop sharply as task count grows, while Fast‑Retry achieves exponential performance gains.
Below is a performance comparison of the three frameworks:
Even with 1,000,000 tasks, Fast‑Retry outperforms Spring‑Retry and Guava‑Retry at 50 tasks by a large margin because it continues working while other frameworks are idle during retry intervals.
Beyond performance, Spring‑Retry is cumbersome and does not support result‑based retry, while Guava‑Retry lacks annotation‑based declarative usage.
Quick Start
Import Dependency
<dependency>
<groupId>io.github.burukeyou</groupId>
<artifactId>fast-retry-all</artifactId>
<version>0.2.0</version>
</dependency>Use Retry Queue
RetryTaskconfigures retry logic such as retry count, interval, and result handling. For simple use, prefer FastRetryBuilder or the @FastRetry annotation. RetryQueue is the core executor, similar to a thread‑pool API.
ExecutorService executorService = Executors.newFixedThreadPool(8);
RetryQueue queue = new FastRetryQueue(executorService);
RetryTask<String> task = new RetryTask<String>() {
int result = 0;
@Override
public long waitRetryTime() { return 2000; }
@Override
public boolean retry() { return ++result < 5; }
@Override
public String getResult() { return result + ""; }
};
CompletableFuture<String> future = queue.submit(task);
log.info("Task finished, result:{}", future.get());Use FastRetryBuilder
The builder still uses RetryQueue underneath but simplifies RetryTask construction.
RetryResultPolicy<String> resultPolicy = result -> result.equals("444");
FastRetryer<String> retryer = FastRetryBuilder.<String>builder()
.attemptMaxTimes(3)
.waitRetryTime(3, TimeUnit.SECONDS)
.retryIfException(true)
.retryIfExceptionOfType(TimeoutException.class)
.exceptionRecover(true)
.resultPolicy(resultPolicy)
.build();
CompletableFuture<String> future = retryer.submit(() -> {
log.info("retry");
if (0 < 10) {
throw new TimeoutException("test");
}
return "444";
});
String o = future.get();
log.info("Result{}", o);Use @FastRetry Annotation
The annotation integrates with Spring, allowing methods marked with @FastRetry to be proxied and executed asynchronously.
Enable in a Spring configuration class with @EnableFastRetry.
When the return type is CompletableFuture, the method runs asynchronously; otherwise it blocks.
@FastRetry(retryWait = @RetryWait(delay = 2))
public String retryTask() {
return "success";
}
@FastRetry(retryWait = @RetryWait(delay = 2))
public CompletableFuture<String> retryTask() {
return CompletableFuture.completedFuture("success");
}Custom Retry Annotation
If you need a business‑specific annotation, define your own annotation with @FastRetry and specify a custom AnnotationRetryTaskFactory. The default implementation is FastRetryAnnotationRetryTaskFactory.
Usage Recommendations
Regardless of the construction method, prefer asynchronous retry (methods returning CompletableFuture) and use whenComplete to handle results.
Comparison Case
A weather‑service retry task requires N attempts to obtain a city's weather. Executing 1,000 cities with Fast‑Retry takes about 10 seconds, while Spring‑Retry takes roughly 1,256 seconds.
// Spring‑Retry test (simplified)
@Retryable(maxAttempts = 100, backoff = @Backoff(delay = 2000))
public WeatherResult getSpringWeather(String city) { ... }
// Fast‑Retry test (simplified)
@FastRetry(maxAttempts = 100, retryWait = @RetryWait(delay = 2, timeUnit = TimeUnit.SECONDS))
public CompletableFuture<WeatherResult> getFutureWeather(String city) { ... }Why Fast‑Retry Is Faster
Asynchronous Execution : Runs retry logic without blocking the main thread, improving responsiveness and throughput.
Non‑Blocking I/O : Utilizes non‑blocking I/O for network or file operations, freeing thread resources.
Optimized Retry Strategies : Supports customizable attempts, intervals, and back‑off algorithms such as exponential back‑off.
Resource Utilization : Reuses connections and threads to reduce creation overhead.
Error Handling : Quickly identifies and processes errors, reducing overhead.
Integration & Extensibility : Easy to integrate into existing systems and extend as needed.
Avoid Unnecessary Retries : Skips retries for hopeless errors based on type or conditions.
Performance Monitoring : May include monitoring features to detect bottlenecks.
Other
GitHub project: https://github.com/burukeYou/fast-retry
Maven repository: https://central.sonatype.com/artifact/io.github.burukeyou/fast-retry-all
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.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!
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.
