How Xxl-Job Works: Inside the Lightweight Distributed Scheduler
This article explains the core concepts, architecture, and implementation details of Xxl-Job, a lightweight distributed task scheduling platform, covering the scheduler center, executor, job handling, demo setup, routing strategies, trigger mechanisms, and result callbacks.
Core Concepts
Hello everyone, I am Su San. This section introduces the three core components of Xxl-Job.
1. Scheduler Center
The scheduler center is a standalone web service that triggers scheduled tasks, provides a UI for managing task triggers, stores data in a shared database, and can run in cluster mode where instances share data via the database without direct communication.
2. Executor
An executor runs the actual job logic. Each service instance corresponds to one executor instance, and you can name the executor after the service for convenience.
3. Task
A task is the unit of work; an executor can contain multiple tasks.
In summary, the scheduler center controls when tasks are triggered, while the executor actually runs the tasks. This separation makes tasks flexible, callable at any time, and triggerable by different scheduling rules.
Demo
1. Build Scheduler Center
Download the source code from https://github.com/xuxueli/xxl-job.git, modify the database connection, and execute the SQL files under /doc/db.
Start the jar (or run locally) and access the console at http://localhost:8080/xxl-job-admin/toLogin with default credentials admin/123456.
2. Add Executor and Task
Add an executor named sanyou-xxljob-demo and a task named TestJob with a cron expression that runs every second.
Enable the task.
Creating executor and task is just CRUD without complex business logic.
Result: every second the executor runs TestJob and prints TestJob任务执行了。。。.
3. Create Executor and Task
Add Maven dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.4.0</version>
</dependency>
</dependencies>Configure the XxlJobSpringExecutor bean:
@Configuration
public class XxlJobConfiguration {
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
XxlJobSpringExecutor executor = new XxlJobSpringExecutor();
executor.setAdminAddresses("http://localhost:8080/xxl-job-admin");
executor.setAppname("sanyou-xxljob-demo");
executor.setPort(9999);
executor.setAccessToken("default_token");
executor.setLogPath("./");
return executor;
}
}Define the job method:
@Component
public class TestJob {
private static final Logger logger = LoggerFactory.getLogger(TestJob.class);
@XxlJob("TestJob")
public void testJob() {
logger.info("TestJob任务执行了。。。");
}
}When the project runs, the job prints the message each second.
Executor Startup
1. Initialize JobHandler
The executor implements SmartInitializingSingleton, so after bean creation it calls afterSingletonsInstantiated to scan Spring beans with @XxlJob, creates MethodJobHandler objects, and stores them in a local cache keyed by job name.
2. Create HTTP Server
The executor starts a Netty‑based HTTP server on the configured port (e.g., 9999) to receive requests from the scheduler.
3. Register to Scheduler Center
When the executor starts, a registration thread sends its name, IP and port to the scheduler so the scheduler can invoke it.
Task Triggering Mechanism
1. How tasks are triggered
The scheduler runs a thread that queries the xxl_job_info table for jobs whose next trigger time is within the next 5 seconds, applies the expiration strategy (ignore or fire immediately), and updates the next trigger time.
To guarantee only one scheduler instance triggers a job, a distributed lock is obtained via
SELECT * FROM xxl_job_lock WHERE lock_name='schedule_lock' FOR UPDATE.
2. Fast/slow thread pools
Trigger requests are first handled by a fast thread pool. If a job’s trigger latency exceeds 500 ms more than 10 times in a minute, it is moved to a slow thread pool to avoid blocking other jobs.
3. Executor instance selection
Routing strategies (first, last, round‑robin, random, consistent hash, LFU, LRU, failover, busy‑over, broadcast) determine which executor instance receives the request.
4. Executor execution flow
Scheduler’s HTTP request is processed by ExecutorBizImpl. A dedicated JobThread is created for the job, which pulls the job from an in‑memory queue. Blocking strategies (serial, discard, cover) control what happens when the executor is already processing the same job.
5. Result callback
After execution, the JobThread puts the result into a queue. A TriggerCallbackThread continuously batches results and sends them back to the scheduler, which updates job status and handles retries or child tasks.
Conclusion
The Xxl‑Job architecture is lightweight and straightforward. This article covered the core logic; logging was omitted for brevity.
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.
Su San Talks Tech
Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.
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.
