Deep Dive into Xxl-Job Core Architecture: How It Works and Why
This article explains Xxl-Job’s lightweight distributed scheduling architecture, covering the admin console, executor startup, JobHandler initialization, HTTP server registration, task triggering logic with scheduling threads, fast/slow thread pools, routing and blocking strategies, and result callbacks, illustrated with code snippets and diagrams.
Core Concepts
Xxl-Job consists of three components: the admin console (a web service that triggers scheduled tasks), the executor (a service instance that runs the job logic), and the job (the unit of work). The admin console stores configuration in a shared database and can run in a cluster; instances communicate only through the database.
Demo Setup
Clone the source code from https://github.com/xuxueli/xxl-job.git, modify the database connection, and execute the SQL scripts under /doc/db. Build and run the admin jar, then open http://localhost:8080/xxl-job-admin/toLogin with the default credentials admin/123456.
Add an executor named sanyou-xxljob-demo and a job called TestJob with a cron expression that runs every second. After creation, enable the job (it is disabled by default).
The job implementation is a simple Spring bean:
@Component
public class TestJob {
private static final Logger logger = LoggerFactory.getLogger(TestJob.class);
@XxlJob("TestJob")
public void testJob() {
logger.info("TestJob任务执行了。。。");
}
}When the executor runs, it prints "TestJob任务执行了。。。" every second.
Executor Startup
The executor entry point is XxlJobSpringExecutor , which implements SmartInitializingSingleton. During bean initialization, its afterSingletonsInstantiated method performs three key actions:
1. Initialize JobHandlers
JobHandler is the wrapper for a scheduled task. Xxl-Job provides three implementations:
MethodJobHandler – invokes a method via reflection.
GlueJobHandler – allows dynamic Java code editing through the GLUE IDE.
ScriptJobHandler – executes scripts (e.g., BEAN, GLUE(Java) or other script modes).
During startup, the executor scans the Spring context for beans annotated with @XxlJob, creates a MethodJobHandler for each, and stores them in a local Map keyed by job name.
2. Create an HTTP Server
The executor launches a Netty‑based HTTP server on the port configured in XxlJobSpringExecutor (e.g., 9999). This server receives task‑trigger requests from the admin console.
Requests are delegated to ExecutorBizImpl, which implements the ExecutorBiz interface. The admin side uses ExecutorBizClient to send HTTP calls.
3. Register to the Admin Console
A registration thread sends the executor’s name, IP, and port to the admin database so the console can locate the executor.
"The admin console can be thought of as a registration center."
Task Triggering Mechanism
The admin console runs a scheduling thread that queries the xxl_job_info table for jobs whose next fire time is within the next 5 seconds (the hard‑coded pre‑read window). It classifies tasks into three buckets based on how far the next fire time is from the current time.
For tasks overdue by more than 5 s, the admin applies the configured schedule‑over‑expire strategy (ignore or execute immediately). Tasks within the 5 s window are placed on a time‑wheel for near‑future execution. The scheduling thread repeats this loop indefinitely.
To ensure only one admin instance triggers a given task, Xxl‑Job uses a database‑based distributed lock:
select * from xxl_job_lock where lock_name = 'schedule_lock' for updateFast/Slow Thread Pools
When a task meets its trigger condition, the admin hands the task to a thread pool. Xxl‑Job maintains two pools: a fast pool for normal tasks and a slow pool for tasks whose HTTP trigger latency exceeds 500 ms and has more than 10 slow occurrences within a minute. This prevents long‑running triggers from blocking other tasks.
Executor Routing Strategies
When multiple executor instances exist, the admin selects one based on the job’s routing strategy . Supported algorithms include:
First, Last, Round‑Robin, Random – straightforward selections.
Consistent Hash – distributes tasks based on a hash of the job key.
Least Frequently Used (LFU) – chooses the instance with the fewest recent executions (cache resets every 24 h).
Least Recently Used (LRU) – picks the instance that has not been accessed recently.
Failover – selects any instance that responds successfully.
Busy‑Transfer – avoids instances currently executing a long‑running task.
Sharding Broadcast – splits the workload across all instances using a shard index and total count.
For sharding broadcast, the helper methods XxlJobHelper#getShardIndex and XxlJobHelper#getShardTotal provide the shard number and total shards respectively.
Executor Task Execution
Upon receiving a trigger request, ExecutorBizImpl creates a dedicated JobThread for the job. The thread places the job into an in‑memory queue, from which it pulls tasks for execution. This design isolates jobs and enables queue‑based control.
If the selected executor instance is already busy with the same job, the admin applies a blocking strategy (single‑machine serial, discard later triggers, or overwrite previous triggers). The overwrite mode interrupts the previous JobThread via Thread#interrupt, though the interrupted task may still run to completion.
"Interrupt is implemented via Thread#interrupt, so the running task may continue."
Result Callback
After a job finishes, the executor pushes the result into a memory queue. A dedicated TriggerCallbackThread continuously drains this queue and batches the results back to the admin console, which updates the job’s execution status and handles retries or downstream triggers.
JobThread → result queue.
TriggerCallbackThread → admin.
Admin updates status, retries, sub‑jobs, etc.
Overall Architecture
The official architecture diagram (slightly outdated) shows the admin console, executors, and the communication flow. The original RPC layer (xxl‑rpc) has been replaced by HTTP to simplify cross‑language integration. Logging is omitted from the discussion but serves only as an auxiliary feature.
In summary, Xxl‑Job provides a lightweight yet powerful distributed scheduling solution with clear separation between scheduling logic and execution, flexible routing, and extensible handler mechanisms.
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.
Shepherd Advanced Notes
Dedicated to sharing advanced Java technical insights, daily work snippets, and the power of persistent effort.
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.
