How to Build a High‑Performance Log Replay Engine with Java DelayQueue
This article explains the design and implementation of a timestamp‑based log replay engine that replays HTTP traffic using Java's DelayQueue, thread pools, and custom data structures, and provides performance test results demonstrating its ability to handle hundreds of thousands of requests per second.
Background and Motivation
The author previously created a first‑generation log replay engine that simply re‑sent recorded HTTP requests. After studying goreplay, the understanding of replay mechanisms was refined to a timestamp‑driven approach: capture traffic with timestamps, sort it, and replay it according to the original timing.
Solution Overview
The new design keeps the existing HTTP‑focused replay components and adds three main steps:
Log cleaning – parse normalized logs into objects containing the HTTP request parts required by the engine.
Timestamp sorting – usually handled by external tools, but compatibility work is needed because the logs come from an existing component.
Replay – use a thread pool and a connection pool to achieve high performance, and integrate with the current distributed architecture.
Core Implementation Details
Data Structures
Define com.funtester.frame.execute.ReplayConcurrent.ReplayLog to store each request's URL and timestamp.
Maintain a list com.funtester.frame.execute.ReplayConcurrent#logs for all log objects (memory‑resident for up to millions of entries).
Use a java.util.concurrent.DelayQueue ( #logDelayQueue) as the replay queue, feeding it from #logs after cloning with adjusted timestamps.
Provide a handler method #handle that wraps a log entry into an HttpRequestBase and sends it.
Producer Logic
Read the log file, create ReplayLog objects, and add them to the delay queue if the timestamp is non‑zero.
Convert the queue to a list, record the first timestamp, then clear the queue.
Spawn a configurable number of producer threads (default 2) that continuously add cloned log entries to the delay queue, adjusting timestamps based on the elapsed time since the start.
Control queue length with a custom max‑length check (default 800 000) to avoid memory overflow.
Consumer Logic
Consumers also run asynchronously, pulling entries from the delay queue using DelayQueue#poll(long, TimeUnit) to avoid blocking.
Each pulled entry is submitted to the thread pool, where the handler is invoked multiple times (configurable #multiple) to simulate traffic bursts.
Metrics such as total QPS, active thread count, and per‑thread efficiency are logged periodically.
Code Sample
package com.funtester.frame.execute;
import java.util.concurrent.*;
class ReplayConcurrent extends SourceCode {
private static Logger logger = LogManager.getLogger(ReplayConcurrent.class);
static ThreadPoolExecutor executor;
static final int MAX_LENGTH = 800000;
int threadNum = 2;
// ... fields omitted for brevity ...
void start() {
// read logs, fill DelayQueue, start producer & consumer threads
}
void stop() { /* shutdown logic */ }
static class ReplayLog extends AbstractBean implements Delayed {
int timestamp; String url;
// constructors, getDelay, compareTo, clone methods
}
}Self‑Test and Results
A small test program creates a ReplayConcurrent instance with a sample log file and a simple HTTP GET handler. The engine reports QPS values ranging from ~23 000 to ~39 000 with varying active thread counts, confirming its ability to sustain high request rates.
Sample output:
10:56:18 F-5 TestReplay, actual QPS:23162 active threads:0 single‑thread efficiency:23162
10:56:23 F-5 TestReplay, actual QPS:36575 active threads:6 single‑thread efficiency:6095
... (more lines) ...Conclusion
By leveraging DelayQueue for time‑ordered replay, thread pools for concurrency, and careful queue‑size management, the engine can reliably replay millions of HTTP requests with precise timing, making it suitable for performance testing, traffic simulation, and debugging production workloads.
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.
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.
