PowerJob Overview: Selection Rationale, Architecture, Task Types, and Scheduling Strategies with Code Samples
This article introduces the PowerJob distributed task framework, explains why it was chosen, details its architecture and high‑availability design, demonstrates various job types—including standalone, broadcast, map, and map‑reduce—with Java code examples, and covers scheduling options such as CRON, fixed‑rate, and fixed‑delay execution.
1. Why Choose PowerJob
PowerJob is a young, lightweight distributed task framework that requires only MySQL and no external services like Zookeeper. It has a simple codebase, is easy to customize (e.g., integrating a custom service‑discovery platform), and offers comprehensive features.
Since its public release only three months ago, PowerJob has gathered 1.8k stars on GitHub and is already adopted by several large companies and institutions.
2. PowerJob Workflow
2.1 Basic Concepts
An app represents a project, a worker is a node belonging to that app, a job is a task (simple scheduled or complex MapReduce) associated with an app, and the server is the PowerJob node responsible for listening and dispatching tasks. The server can be deployed as a single instance or a cluster.
2.2 App‑Server Binding
Workers are configured with server addresses, register themselves on startup, and the server then knows how many workers belong to each app. Workers run two periodic tasks: a heartbeat to report liveness and a discovery task to sync server state.
2.3 High Availability
To avoid a single point of failure, a backup server is added. When the primary server crashes, PowerJob uses a discovery mechanism to fail over to the standby server. A typical HA deployment uses three machines: one master and two slaves.
2.4 Server Scheduling
The server polls and dispatches jobs to workers according to the configured schedule.
2.5 Deployment Steps
Deploy the PowerJob server (usually pre‑deployed).
Develop job classes in your app project and specify a server for scheduling.
Register the app in the PowerJob client.
Start the app so that its workers bind to the server.
Configure the job in the PowerJob UI (cron expression, concurrency, map‑reduce flag, etc.).
3. Job Types and Validation
3.1 Defining a PowerJob Task
Job classes must implement PowerJob interfaces. The framework obtains instances from the Spring context or via reflection.
3.2 Standalone (Single‑Machine) Task
@Slf4j
@Component
public class StandaloneProcessor implements BasicProcessor {
@Override
public ProcessResult process(TaskContext context) {
log.info("Simple scheduled task triggered! Params: {}", context.getJobParams());
return new ProcessResult(true, context + ": " + true);
}
}After publishing the job and configuring its schedule in the UI, the task runs and logs the output.
3.3 Broadcast Task
Broadcast mode triggers the job on every worker node.
@Slf4j
@Component
public class BroadcastProcessorDemo extends BroadcastProcessor {
@Override
public ProcessResult preProcess(TaskContext context) throws Exception {
log.info("Before broadcast, params: {}", context.getJobParams());
return new ProcessResult(true);
}
@Override
public ProcessResult process(TaskContext context) throws Exception {
log.info("Broadcast core logic! Params: {}", context.getJobParams());
return new ProcessResult(true);
}
@Override
public ProcessResult postProcess(TaskContext context, List
results) throws Exception {
log.info("Broadcast finished, reduce triggered! Context: {}, Results: {}",
JSONObject.toJSONString(context), JSONObject.toJSONString(results));
return new ProcessResult(true, "success");
}
}3.4 Map Task (Batch Splitting)
@Slf4j
@Component
public class MapProcessorDemo extends MapProcessor {
private static final int batchSize = 100;
private static final int batchNum = 2;
@Override
public ProcessResult process(TaskContext context) throws Exception {
if (isRootTask()) {
log.info("Root task, performing split...");
List
subTasks = Lists.newLinkedList();
for (int j = 0; j < batchNum; j++) {
SubTask sub = new SubTask();
sub.siteId = j;
sub.itemIds = Lists.newLinkedList();
for (int i = 0; i < batchSize; i++) {
sub.itemIds.add(i);
}
subTasks.add(sub);
}
return map(subTasks, "MAP_TEST_TASK");
} else {
SubTask sub = (SubTask) context.getSubTask();
log.info("Sub‑task received: {}", JSON.toJSONString(sub));
return new ProcessResult(true, "RESULT:true");
}
}
@Getter @NoArgsConstructor @AllArgsConstructor
private static class SubTask {
private Integer siteId;
private List
itemIds;
}
}3.5 MapReduce Task (Batch + Reduce)
@Slf4j
@Component
public class MapReduceProcessorDemo extends MapReduceProcessor {
private static final int batchSize = 100;
private static final int batchNum = 2;
@Override
public ProcessResult process(TaskContext context) {
if (isRootTask()) {
log.info("Root task, splitting...");
List
subTasks = Lists.newLinkedList();
for (int j = 0; j < batchNum; j++) {
SubTask sub = new SubTask();
sub.siteId = j;
sub.itemIds = Lists.newLinkedList();
for (int i = 0; i < batchSize; i++) {
sub.itemIds.add(i);
}
subTasks.add(sub);
}
return map(subTasks, "MAP_TEST_TASK");
} else {
SubTask sub = (SubTask) context.getSubTask();
log.info("Sub‑task received: {}", JSON.toJSONString(sub));
return new ProcessResult(true, "RESULT:true");
}
}
@Override
public ProcessResult reduce(TaskContext context, List
results) {
log.info("Reduce triggered! Context: {}, Results: {}",
JSONObject.toJSONString(context), JSONObject.toJSONString(results));
return new ProcessResult(true, "RESULT:true");
}
@Getter @NoArgsConstructor @AllArgsConstructor
private static class SubTask {
private Integer siteId;
private List
itemIds;
}
}3.6 Workflow Tasks
A workflow follows a sequence such as Task A → Task B → Task C . The workflow has its own trigger, so a CRON expression set on individual tasks is ignored.
4. Scheduling Types and Validation
4.1 CRON Expressions
PowerJob supports standard CRON expressions but not second‑level granularity. If a task takes longer than its interval, the next execution still follows the original schedule.
4.2 Fixed‑Rate Scheduling
Tasks can be configured to run at a constant rate regardless of execution time.
4.3 Fixed‑Delay Scheduling
In fixed‑delay mode, the next execution starts only after the previous run finishes, making the schedule effectively serial.
5. Additional Resources
For details on job creation form fields, refer to the official documentation: https://www.yuque.com/powerjob/guidence/nyio9g#v8uF4
For workflow configuration guidance, see: https://www.yuque.com/powerjob/guidence/ysug77#xgylz (note that the UI may be cumbersome).
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.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.