想在後臺管理系統介面化管理 Quartz Job,就必須將所有 Job Class 導入管理系統中,但也強迫系統成為 Quartz Cluster 節點之一,導致伺服器資源被 Job 占用,所以開發一套基於事件綁定的排程任務管理器,解決任務管理和任務執行的相依性
- Separate job managers and executors on different project
- Spring Boot 2+
- Java 11+
<dependency>
<groupId>io.github.babyblue94520</groupId>
<artifactId>event-job</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
event-job:
instance: eventJobScheduler
reload-interval: 60000
thread-count: 20 # default processors * 2
check-wait-time: 1000 # Wait time to check if a job is being processed
@EnableEventJob
public class EventJobConfig {
}
@EnableEventJob
public class EventJobConfig {
@Autowired
private EventScheduler eventScheduler;
@Override
public void afterPropertiesSet() throws Exception {
eventScheduler.add(EventJob.builder()
.group("group")
.name("name")
.event("event")
.cron("*/1 * * * * ?")
.timezone("+00:00")
.build());
}
}
@EnableEventJob
public class EventJobRegister implements InitializingBean{
@Autowired
private EventScheduler eventScheduler;
@Override
public void afterPropertiesSet() throws Exception {
eventScheduler.addHandler(eventJob.getEvent(), (eventJob2) -> {
// Do something
});
}
}
- Notify jobs changes immediately
Example
import java.util.concurrent.CopyOnWriteArrayList;
@Log4j2
@Service
public class EventJobMessageServiceImpl implements EventJobMessageService {
private static final List<Consumer<String>> listeners = new CopyOnWriteArrayList<>();
private static final ExecutorService executor = Executors.newFixedThreadPool(1);
@Override
public String send(String body) {
executor.submit(() -> {
listeners.forEach(consumer -> consumer.accept(body));
});
return body;
}
@Override
public Consumer<String> addListener(Consumer<String> listener) {
listeners.add(listener);
return listener;
}
}
@EnableEventJob
public class EventJobConfig {
@Autowired
private EventScheduler eventScheduler;
@Override
public void afterPropertiesSet() throws Exception {
// Execute after 'group-name' job completes.
eventScheduler.add(EventJob.builder()
.group("after-group")
.name("after-name")
.event("after-event")
.afterGroup("group")
.afterName("name")
.timezone("+00:00")
.build());
}
}