Backend Development 15 min read

Guide to Using the XXL‑JOB Distributed Task Scheduling Framework with Spring Boot

This article introduces the XXL‑JOB open‑source distributed scheduler, compares it with Quartz and other solutions, and provides a step‑by‑step tutorial for server deployment, executor configuration, task development, execution, logging, and the underlying Netty‑based communication design, complete with code examples.

Top Architect
Top Architect
Top Architect
Guide to Using the XXL‑JOB Distributed Task Scheduling Framework with Spring Boot

Task scheduling is a common component in Java projects, often using Quartz in the Spring framework. Popular distributed schedulers such as Elastic‑Job and Azkaban are built on top of Quartz.

The article introduces XXL‑JOB , a lightweight open‑source distributed scheduling framework that consists of an admin (management) console and one or more executor nodes. The admin console handles task configuration and log viewing, while each executor runs the actual job logic.

Project Introduction

XXL‑JOB can be quickly started by cloning the GitHub repository https://github.com/xuxueli/xxl-job , importing the xxl-job-admin module into a new Spring Boot project, and executing the provided SQL script to create the required tables.

1. Server Deployment

Create a new Spring Boot project, copy the xxl-job-admin files and pom.xml into it, and configure the database connection in application.properties . After building the project, start it and access the admin UI at http://localhost:8080/xxl-job-admin/ (default admin/123456).

2. Executor Configuration

Create a separate module for the executor, add the xxl-job-core dependency, and provide two configuration files (e.g., application-9998.properties and application-9999.properties ) with different server.port and xxl.job.executor.port values to simulate a distributed environment. Define a Java config class that creates an XxlJobSpringExecutor bean.

3. Task Development

Two common ways to create tasks are shown:

Method‑annotation tasks: add @XxlJob("myJob") on a Spring bean method.

API‑based tasks: use the provided XxlJobInfoService to register jobs programmatically.

Shard‑broadcast tasks: configure the job to run on all executors.

4. Task Execution

In the admin console, create a job with a CRON expression and specify the handler name (e.g., myJobAnnotationHandler ). The UI allows manual triggering, parameter input, and viewing of execution results.

5. Task Logging

XXL‑JOB records detailed logs for each execution, including parent‑child relationships, execution remarks, and console output from XxlJobLogger .

Communication Design

XXL‑JOB uses Netty HTTP for communication between the admin console and executors. The design hides communication details behind dynamic proxy interfaces ( ExecutorBiz and AdminBiz ) and performs all network I/O asynchronously.

Key code snippets:

public static ReturnT
runExecutor(TriggerParam triggerParam, String address) {
    ReturnT
runResult = null;
    try {
        ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(address);
        // asynchronous handling, final synchronous result
        runResult = executorBiz.run(triggerParam);
    } catch (Exception e) {
        logger.error(">>>>>>>>>>> xxl-job trigger error, please check if the executor[{}] is running.", address, e);
        runResult = new ReturnT
(ReturnT.FAIL_CODE, ThrowableUtil.toString(e));
    }
    StringBuffer runResultSB = new StringBuffer(I18nUtil.getString("jobconf_trigger_run") + ":");
    runResultSB.append("
address:").append(address);
    runResultSB.append("
code:").append(runResult.getCode());
    runResultSB.append("
msg:").append(runResult.getMsg());
    runResult.setMsg(runResultSB.toString());
    return runResult;
}
// Proxy invocation for synchronous call
if (CallType.SYNC == callType) {
    XxlRpcFutureResponse futureResponse = new XxlRpcFutureResponse(invokerFactory, xxlRpcRequest, null);
    try {
        client.asyncSend(finalAddress, xxlRpcRequest);
        XxlRpcResponse xxlRpcResponse = futureResponse.get(timeout, TimeUnit.MILLISECONDS);
        if (xxlRpcResponse.getErrorMsg() != null) {
            throw new XxlRpcException(xxlRpcResponse.getErrorMsg());
        }
        return xxlRpcResponse.getResult();
    } catch (Exception e) {
        logger.info(">>>>>>>>>>> xxl-rpc, invoke error, address:{}, XxlRpcRequest{}", finalAddress, xxlRpcRequest);
        throw (e instanceof XxlRpcException) ? e : new XxlRpcException(e);
    } finally {
        futureResponse.removeInvokerFuture();
    }
}
// Future response handling (thread wait/notify)
public void setResponse(XxlRpcResponse response) {
    this.response = response;
    synchronized (lock) {
        done = true;
        lock.notifyAll();
    }
}
@Override
public XxlRpcResponse get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
    if (!done) {
        synchronized (lock) {
            try {
                if (timeout < 0) {
                    lock.wait();
                } else {
                    long timeoutMillis = (TimeUnit.MILLISECONDS == unit) ? timeout : TimeUnit.MILLISECONDS.convert(timeout, unit);
                    lock.wait(timeoutMillis);
                }
            } catch (InterruptedException e) {
                throw e;
            }
        }
    }
    if (!done) {
        throw new XxlRpcException("xxl-rpc, request timeout at:" + System.currentTimeMillis() + ", request:" + request.toString());
    }
    return response;
}

The combination of dynamic proxies, asynchronous queues, and Netty I/O results in a highly responsive scheduler that minimizes the time spent in Netty worker threads, thereby improving throughput.

Overall, the guide provides a complete hands‑on walkthrough for setting up XXL‑JOB, configuring multiple executors, developing various job types, and understanding the underlying communication mechanisms.

BackendJavadistributed schedulingNettySpring Bootxxl-jobTask Execution
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.