All Products
Search
Document Center

SchedulerX:Graceful shutdown for scheduled jobs

Last Updated:Jun 02, 2026

When an application restarts during a release, running scheduled jobs are interrupted, which can cause incomplete data processing or inconsistent states. SchedulerX graceful shutdown lets in-flight jobs complete before the application process exits.

How it works

When graceful shutdown is enabled, the application process intercepts shutdown signals and delays its exit until in-flight jobs finish, up to an optional timeout.

  1. A shutdown signal is received — for example, kill -15, a Spring Boot shutdown event, or an HTTP request.

  2. Running jobs and tasks continue executing based on the configured shutdown mode.

  3. After all qualifying jobs complete or the timeout expires, the application process exits.

Shutdown flow diagram

image

Prerequisites

Before you begin, make sure you have:

  • SchedulerX client version 1.10.8 or later

Shutdown modes

SchedulerX supports two graceful shutdown modes for jobs running in standalone mode and distributed mode:

Mode

Behavior

When to use

WAIT_ALL (recommended)

The application exits only after all jobs and tasks complete, including those in queue.

Every job must finish to maintain data consistency.

WAIT_RUNNING

The application exits after currently running jobs and tasks complete. Queued jobs are dropped.

Queued jobs can be safely retried or skipped.

Configure graceful shutdown

Add the following properties to your Spring Boot configuration:

# Shutdown mode: controls which jobs are waited for before exit.
# WAIT_ALL: exit only after all jobs and queued tasks complete (recommended for data consistency)
# WAIT_RUNNING: exit after currently running jobs complete; queued jobs are dropped
# Not configured by default (graceful shutdown is disabled).
spring.schedulerx2.graceShutdownMode=WAIT_ALL

# Maximum time (in seconds) to wait before forcing shutdown.
# Not configured by default (no timeout — a stuck job can block shutdown indefinitely).
spring.schedulerx2.graceShutdownTimeout=10

# Enable the built-in HTTP shutdown endpoint. Default: false.
spring.schedulerx2.httpServerEnable=true

# Port for the HTTP shutdown endpoint. Default: 51886.
spring.schedulerx2.httpServerPort=51886

Parameter

Description

Default

spring.schedulerx2.graceShutdownMode

Shutdown mode: WAIT_ALL or WAIT_RUNNING

Not configured (disabled)

spring.schedulerx2.graceShutdownTimeout

Maximum wait time in seconds before the process is forcefully terminated

Not configured (no timeout)

spring.schedulerx2.httpServerEnable

Enable the HTTP shutdown endpoint

false

spring.schedulerx2.httpServerPort

Port for the HTTP shutdown endpoint

51886

Important

Set graceShutdownTimeout to a value appropriate for your longest-running job. Without a timeout, a stuck job can block the application from ever shutting down.

Trigger graceful shutdown

Choose one of the following methods. Method 1 (kill -15) works for any Java application. Methods 2 and 3 are HTTP-based alternatives.

Method 1: Send SIGTERM with kill -15

SchedulerX registers a JVM shutdown hook that intercepts SIGTERM. Send the signal to the application process:

kill -15 <PID>

The process completes running jobs according to the configured shutdown mode, then exits.

Important

Do not run kill -9 directly. SIGKILL bypasses the JVM shutdown hook and terminates the process immediately, skipping graceful shutdown. Use kill -9 only after kill -15 fails to stop the process within an acceptable time.

Method 2: Use the Spring Boot actuator shutdown endpoint

For Spring Boot applications, use the built-in actuator to trigger a shutdown event. SchedulerX responds to Spring container shutdown events and completes running jobs before the application exits.

  1. Add the actuator dependency to your pom.xml:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  1. Enable the shutdown endpoint in your application properties:

management.endpoint.shutdown.enabled=true
management.endpoints.web.exposure.include=shutdown
  1. Trigger the shutdown:

curl -X GET http://<node-ip>:<port>/actuator/shutdown

Method 3: Use the SchedulerX HTTP endpoint

Enable the built-in SchedulerX HTTP endpoint:

spring.schedulerx2.httpServerEnable=true
spring.schedulerx2.httpServerPort=51886

Trigger the shutdown:

curl -X GET http://<node-ip>:51886/schedulerx/worker/shutdown

Integrate into deployment workflows

Self-managed continuous delivery (CD) pipeline

Include graceful shutdown logic in the stop script of your CD pipeline. The following example sends SIGTERM, polls for process exit, and falls back to SIGKILL after a timeout:

image
# After starting the application, write the PID to app.pid.
PID="{Application deployment path}/app.pid"
FORCE=1
if [ -f ${PID} ]; then
  TARGET_PID=`cat ${PID}`
  kill -15 ${TARGET_PID}
  loop=1
  while(( $loop<=5 ))
  do
    # health: Check whether the application process is still running.
    # Replace with your own health check command.
    health
    if [ $? == 0 ]; then
      echo "check $loop times, current app has not stop yet."
      sleep 5s
      let "loop++"
    else
      FORCE=0
      break
    fi
  done
  if [ $FORCE -eq 1 ]; then
  	echo "App(pid:${TARGET_PID}) stop timeout, forced termination."
    kill -9 ${TARGET_PID}
  fi
  rm -rf ${PID}
  echo "App(pid:${TARGET_PID}) stopped successful."
fi

Kubernetes PreStop hook

Use the Kubernetes Pod preStop lifecycle hook to trigger graceful shutdown before a Pod is terminated. When a Pod is deleted, Kubernetes runs the preStop hook before sending SIGTERM to the container — this is when SchedulerX intercepts the signal and begins draining in-flight jobs.

Option A: Exec script

Run a script or send SIGTERM directly:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: my-app-image:latest
        lifecycle:
          preStop:
            exec:
              # command: ["/bin/sh", "-c", "kill -15 PID && sleep 30"]
              command: ["/bin/sh", "-c", "Script path /stop.sh"] 

Option B: HTTP request

Call the appropriate HTTP endpoint based on your application type:

  • Spring Boot applications: Set path to /actuator/shutdown.

  • Non-Spring applications: Set path to /schedulerx/worker/shutdown after enabling the SchedulerX HTTP endpoint.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: my-app-image:latest
        lifecycle:
          preStop:
            httpGet:
              path: /schedulerx/worker/shutdown
              port: 51886
              scheme: HTTP

Alibaba Cloud platform integration

If you deploy through Enterprise Distributed Application Service (EDAS) or through Microservices Engine (MSE) with Container Service for Kubernetes (ACK), SchedulerX graceful shutdown integrates automatically after you enable graceful shutdown on the platform. For details, see:

Best practices

  • Set a shutdown timeout. Without a timeout, a long-running or stuck job blocks shutdown indefinitely. Set graceShutdownTimeout to a value slightly longer than the expected maximum job duration.

  • Avoid kill -9 as the first action. Always send SIGTERM (kill -15) first and wait for graceful shutdown to complete. Use SIGKILL (kill -9) only after the timeout expires.

  • Use WAIT_ALL for data-sensitive workloads. WAIT_RUNNING drops queued jobs, which can cause missed executions. Choose WAIT_ALL unless queued jobs are safely retriable.

  • Check job status before shutting down. In production, verify no active jobs are running before triggering a shutdown to avoid unnecessary wait times or retries.

  • Test in staging first. Validate your shutdown configuration, timeout, and integration method in a staging environment before applying them to production.