HTTP tasks

Updated at:
Copy as MD

Schedule and run tasks over HTTP or HTTPS without integrating a language-specific SDK. HTTP tasks let you connect legacy services, multi-language microservices, and AI agent workflows to the MSE scheduling center through standard HTTP endpoints.

  • Zero code changes: Expose an HTTP endpoint from any existing service and the scheduling center calls it on schedule. No SDK required.

  • Language-agnostic: Java, Python, Go, Node.js -- any framework that serves HTTP works the same way.

  • AI agent and workflow support: Trigger AI agent pipelines and workflow orchestrations through standard HTTP calls.

Two connection types are available:

  • Kubernetes service: Routes requests directly to pod instances discovered through Kubernetes service endpoints. All tasks in the application share the pod resources associated with the service.

  • Gateway (non-Kubernetes): Routes requests through a gateway to domain names configured at the application level.

Prerequisites

If the current engine version is earlier than 2.3.0, upgrade it to 2.3.0 or later.

Important

The instance restarts during the upgrade.

Choose a connection type

DimensionKubernetes serviceGateway (non-Kubernetes)
Connection patternDirectly accesses backend pod instancesRoutes through a unified gateway
Service discoveryActively listens for Endpoint changes and dynamically maintains the pod listDoes not support service discovery and is unaware of the backend node status
Target granularitySchedules to specific pod IP addresses and ports for point-to-point callsGateway handles internal load balancing; the scheduling center does not see backend nodes
Routing policySingle-instance routing and broadcast shardingDoes not support routing policies; uses the gateway's own routing policy
Broadcast shardingNatively supported for large-scale parallel batch processingNot supported; all tasks run as single-point executions, and cross-node collaborative processing is not possible
Health managementSyncs Endpoint statuses in real time; automatically removes pods that are not ready or have been terminatedRelies on manual maintenance of domain name availability
ScalabilityAdapts to cloud-native environments with automatic scaling and rolling deploymentsBetter suited for traditional architectures or heterogeneous system integration; easy to connect with existing gateway systems
Best forContainerized microservices, sharded batch processing jobs, high-concurrency scheduled tasksNon-container environments, hybrid deployment architectures, legacy system integration, enterprise API scheduling with unified gateway administration

How connection types work

Kubernetes service

Bind a Kubernetes service to an application, and the scheduling center discovers and tracks all pod instances behind that service. Each task only needs an HTTP request path -- the scheduling center selects a target pod based on the routing policy and sends the request directly.

A service discovery thread monitors pod scaling events and health status changes in real time. When pods scale up, scale down, or become unhealthy, the scheduling center automatically syncs the latest pod information with the pod manager.

The pod manager maintains network addresses and health statuses for all pods. Two routing modes are available:

  • Single-instance routing: Sends the request to one selected pod.

  • Broadcast sharding: Sends a request to every pod in the service. The scheduling center injects sharding context -- shard index and total shard count -- into the HTTP request headers, so each pod can process its assigned data partition.

Task execution results are recorded and pushed to Simple Log Service (SLS) for viewing and analysis.

Gateway (non-Kubernetes)

Bind one or more HTTP domain names to an application. All tasks within that application share these domain name configurations.

Each task only needs a request path. The scheduling center selects a domain name based on the routing policy and sends the request to the gateway, which handles authentication, traffic shaping, and load balancing before forwarding to the target service.

The domain name manager supports:

  • Adding, deleting, and modifying domain names

  • Tag-based routing to distribute traffic by business tags

  • Multiple routing policies for different scheduling and load balancing needs

Task execution results are synced to Simple Log Service (SLS).

Set up an HTTP task

  1. Log on to the MSE XXL-JOB console and select a region from the top menu bar.

  2. In the left-side navigation pane, choose Task Scheduling > XXL-JOB Version.

  3. Click your target instance. In the left-side navigation pane, choose Application Management, and then click CreateApplication. Set app type to HTTPApplication, and then click OK.

  4. Connect an HTTP executor to the application. For details, see Connect an HTTP application to an executor.

  5. In the left-side navigation pane, choose Task Management, and then click Create Task. Set Associated Application to the application you created in step 3, and set Job Type to HTTP.

  6. Configure the HTTP request settings.

    ParameterDescription
    Domain nameThe destination domain name for the request.
    PathThe HTTP request path on the target service.
    Request methodThe HTTP method for the request.
    TimeoutThe maximum time to wait for a response.
  7. Configure request parameters as needed.

    ParameterDescription
    HeaderCustom HTTP headers to include in the request.
    QueryQuery string parameters appended to the URL.
    BodyThe request body content.
  8. Configure the response definition to determine how the scheduling center parses task results. Three parsing types are available: response code, response body, and response Body.

  9. Configure the retry policy.

    ParameterDescription
    Number of retriesHow many times to retry after a failure. Set to 0 to disable retries.
    Retry intervalThe time to wait between retry attempts.
    Retry domain name and interface path (optional)If set, retry requests are sent to this alternate endpoint instead of the original.

Implement an HTTP endpoint

The scheduling center sends an HTTP request to your service endpoint on each trigger. Your endpoint receives system headers that identify the task and execution context, and returns a response that the scheduling center parses to determine success or failure.

The following examples show a minimal endpoint that reads the scheduling headers and returns a JSON response.

Python (Flask)

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route("/task/run", methods=["POST"])
def run_task():
    job_id = request.headers.get("schedulerx-jobId")
    job_name = request.headers.get("schedulerx-jobName")
    attempt = request.headers.get("schedulerx-attempt")

    # Add your task logic here
    result = {"status": "success", "jobId": job_id, "jobName": job_name}

    return jsonify(result), 200

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080)

Java (Spring Boot)

import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
import java.util.Map;

@RestController
public class TaskController {

    @PostMapping("/task/run")
    public ResponseEntity<Map<String, Object>> runTask(
            @RequestHeader("schedulerx-jobId") String jobId,
            @RequestHeader("schedulerx-jobName") String jobName,
            @RequestHeader("schedulerx-attempt") String attempt) {

        // Add your task logic here
        Map<String, Object> result = Map.of(
            "status", "success",
            "jobId", jobId,
            "jobName", jobName
        );

        return ResponseEntity.ok(result);
    }
}

Go (net/http)

package main

import (
	"encoding/json"
	"net/http"
)

func runTask(w http.ResponseWriter, r *http.Request) {
	jobId := r.Header.Get("schedulerx-jobId")
	jobName := r.Header.Get("schedulerx-jobName")

	// Add your task logic here
	result := map[string]string{
		"status":  "success",
		"jobId":   jobId,
		"jobName": jobName,
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(result)
}

func main() {
	http.HandleFunc("/task/run", runTask)
	http.ListenAndServe(":8080", nil)
}

Node.js (Express)

const express = require("express");
const app = express();

app.post("/task/run", (req, res) => {
  const jobId = req.headers["schedulerx-jobid"];
  const jobName = req.headers["schedulerx-jobname"];
  const attempt = req.headers["schedulerx-attempt"];

  // Add your task logic here
  res.json({ status: "success", jobId, jobName });
});

app.listen(8080, () => {
  console.log("Task endpoint listening on port 8080");
});

Handle broadcast sharding

When broadcast sharding is enabled, the scheduling center sends a request to every pod and injects sharding context into the headers. Use these headers to partition your workload.

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route("/task/shard", methods=["POST"])
def shard_task():
    shard_index = int(request.headers.get("schedulerx-shardingIndex", 0))
    shard_total = int(request.headers.get("schedulerx-shardingTotal", 1))

    # Partition your data by shard index
    # For example, process records where record_id % shard_total == shard_index
    result = {
        "status": "success",
        "shardIndex": shard_index,
        "shardTotal": shard_total,
        "message": f"Processed shard {shard_index} of {shard_total}"
    }

    return jsonify(result), 200

HTTP request headers

The scheduling center injects the following system headers into each HTTP task request. Use these headers in your endpoint to identify the task, track execution, and implement sharding logic.

HeaderDescriptionExample
schedulerx-appIdApplication ID12
schedulerx-jobIdTask ID35
schedulerx-jobNameTask namehttp-test-job
schedulerx-scheduleTimestampScheduling timestamp (milliseconds)1760164985000
schedulerx-dataTimestampData timestamp (milliseconds)1760164980000
schedulerx-userUser information1344371792
schedulerx-maxAttemptMaximum number of retries3
schedulerx-attemptCurrent retry attempt1
schedulerx-jobExecutionIdTask execution ID1417474640397221891
schedulerx-logIdShard ID (for broadcast sharding)1417474640531439619
schedulerx-shardingIndexShard index (for broadcast sharding)0
schedulerx-shardingTotalTotal number of shards (for broadcast sharding)3