SpringBoot e-commerce project mall (40K + STAR) address: github.com/macrozheng/…
Abstract
Before we talked about a distributed task scheduling framework, PowerJob, which can be used for task scheduling in a visual way. However, sometimes we just need a lightweight task scheduling function, and PowerJob requires a scheduling center. This is where SpringBoot’s Quartz framework comes in handy. This article mainly introduces the use of Quartz in SpringBoot, so that you have more choices in implementing task scheduling!
Introduction of Quartz
Quartz is a powerful open source task scheduling framework that can be integrated into almost any Java application, from small standalone to large distributed. Quartz can be used to create simple or complex task schedules to perform tens of thousands of tasks. Tasks are defined as standardized Java components, and any task written in Java can be executed.
The core concept
There are some core concepts in Quartz that are helpful to understand!
- Scheduler: A task Scheduler in Quartz that can be used to schedule, pause, and delete tasks via Trigger and JobDetail.
- Trigger: in Quartz, a CRON expression can be used to specify the time when a task will be executed. When the time is up, the task will be automatically triggered.
- JobDetail: Details of tasks to be executed in Quartz, including the unique identifier of the task and the specific task to be executed. Data can be sent to the task through JobDataMap.
- Job: The specific task in Quartz, which contains the specific method of performing the task.
CRON expression
A Cron expression is a string containing 6 to 7 time elements that can be used in Quartz to specify the execution time of a task.
CRON syntax format
Seconds Minutes Hours DayofMonth Month DayofWeek
Copy the code
Description of each time element in the CRON format
The time element | The character that can appear | Effective value range |
---|---|---|
Seconds | , – * / | 0-59 |
Minutes | , – * / | 0-59 |
Hours | , – * / | 0-23 |
DayofMonth | , – * /? L W | 0-31 |
Month | , – * / | 1-12 |
DayofWeek | , – * /? L # | 1-7 – SAT or SUN |
Special characters in CRON format
character | role | For example, |
---|---|---|
. | Listing enumerated values | Use 5,10 in the Minutes field to fire at 5 and 10 Minutes each |
– | Indicates trigger range | Use 5-10 in the Minutes field to trigger every minute from 5 to 10 Minutes |
* | Match any value | Using * in the Minutes field means that it fires every minute |
/ | Start time Triggers at fixed intervals | Use 5/10 in the Minutes field to fire once every 5 Minutes and again every 10 Minutes |
? | In DayofMonth and DayofWeek, used to match any value | Used in the DayofMonth domain? Is triggered every day |
# | In DayofMonth, determine the day of the week | 1#3 is the third Sunday |
L | Said the last | Use 5L in DayofWeek to trigger on the last Thursday |
W | Represents valid working days (Monday to Friday) | Use 5W in DayofMonth, and if the 5th falls on a Saturday, it will be triggered once on the 4th of the nearest weekday |
Online CRON expression generator
CRON expressions don’t need to be memorized. use the online generator (cron.qqe2.com/) when needed
Integrate SpringBoot use
Next, we will talk about how to use Quartz in SpringBoot to implement task scheduling. In e-commerce systems, there will often be the need to regularly send emails or in-site letters, so we take this as a scenario to implement!
- There are two ways for Quartz to store task information: memory or database. Here we use database storage. First of all, we need to create Quartz related tables and build table scripts in the project
resources
In the directory, the name istables_mysql.sql
, there are 11 more tables in the database after the successful creation.
- The next in
pom.xml
Add Quartz dependency, SpringBoot official has provided us with a good Starter;
<! - SpringBoot integration QuartZ - >
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
Copy the code
- in
application.yml
Add Quartz related configuration, configuration instructions directly read the note is good, mainly for thescheduler
,jobStore
andthreadPool
To configure;
spring:
quartz:
job-store-type: jdbc # Quartz Task storage type: JDBC or Memory
wait-for-jobs-to-complete-on-shutdown: true Wait for the task to complete while closing
overwrite-existing-jobs: true You can override existing tasks
properties: # Quartz native configuration
org:
quartz:
scheduler:
instanceName: scheduler The scheduler instance name
instanceId: AUTO The scheduler instance ID is automatically generated
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX Scheduling information storage processing class
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate # Use a fully JDBC-compliant driver
tablePrefix: QRTZ_ # Quartz table prefix
useProperties: false # whether to convert JobDataMap attributes to string stores
threadPool:
class: org.quartz.simpl.SimpleThreadPool Specifies a thread pool implementation class that provides a fixed size thread pool for the scheduler
threadCount: 10 Set the number of concurrent threads
threadPriority: 5 # set thread priority
Copy the code
- Create a task scheduling service interface and define three methods, namely, scheduling a task through CRON expression, scheduling a task at a specified time and canceling a scheduled task.
/** * Created by macro on 2020/9/27. */
public interface ScheduleService {
/** * Schedule tasks */ using CRON expressions
String scheduleJob(Class<? extends Job> jobBeanClass, String cron, String data);
/** * Schedules tasks at specified time */
String scheduleFixTimeJob(Class<? extends Job> jobBeanClass, Date startTime, String data);
/** * Cancel the scheduled task */
Boolean cancelScheduleJob(String jobName);
}
Copy the code
- Create a task scheduling business implementation class, through
Scheduler
,CronTrigger
,JobDetail
API implementation related methods;
/** * Created by macro on 2020/9/27. */
@Slf4j
@Service
public class ScheduleServiceImpl implements ScheduleService {
@Autowired
private Scheduler scheduler;
private String defaultGroup = "default_group";
@Override
public String scheduleJob(Class<? extends Job> jobBeanClass, String cron, String data) {
// Create a task to execute
String jobName = UUID.fastUUID().toString();
JobDetail jobDetail = JobBuilder.newJob(jobBeanClass)
.withIdentity(jobName, defaultGroup)
.usingJobData("data", data)
.build();
// Create a trigger to specify the task execution time
CronTrigger cronTrigger = TriggerBuilder.newTrigger()
.withIdentity(jobName, defaultGroup)
.withSchedule(CronScheduleBuilder.cronSchedule(cron))
.build();
// Use the scheduler to schedule tasks
try {
scheduler.scheduleJob(jobDetail, cronTrigger);
} catch (SchedulerException e) {
e.printStackTrace();
log.info("Failed to create a scheduled task!);
}
return jobName;
}
@Override
public String scheduleFixTimeJob(Class<? extends Job> jobBeanClass, Date startTime, String data) {
// Date to CRON expression
String startCron = String.format("%d %d %d %d %d ? %d",
DateUtil.second(startTime),
DateUtil.minute(startTime),
DateUtil.hour(startTime, true),
DateUtil.dayOfMonth(startTime),
DateUtil.month(startTime) + 1,
DateUtil.year(startTime));
return scheduleJob(jobBeanClass, startCron, data);
}
@Override
public Boolean cancelScheduleJob(String jobName) {
boolean success = false;
try {
// Pause the trigger
scheduler.pauseTrigger(new TriggerKey(jobName, defaultGroup));
// Remove the task from the trigger
scheduler.unscheduleJob(new TriggerKey(jobName, defaultGroup));
// Delete the task
scheduler.deleteJob(new JobKey(jobName, defaultGroup));
success = true;
} catch (SchedulerException e) {
e.printStackTrace();
}
returnsuccess; }}Copy the code
- Define the tasks that need to be performed and inherit
QuartzJobBean
Classes that implementexecuteInternal
Three tasks are defined here, namely, regularly sending mail, regularly sending intra-station messages and executing CRON expression tasks;
/** * Created by macro on 2020/9/27. */
@Slf4j
@Component
public class SendEmailJob extends QuartzJobBean {
@Autowired
private ScheduleService scheduleService;
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
Trigger trigger = jobExecutionContext.getTrigger();
JobDetail jobDetail = jobExecutionContext.getJobDetail();
JobDataMap jobDataMap = jobDetail.getJobDataMap();
String data = jobDataMap.getString("data");
log.info("Timed mail operation: {}",data);
// Delete triggers and tasks after completionscheduleService.cancelScheduleJob(trigger.getKey().getName()); }}Copy the code
/** * Created by macro on 2020/9/27. */
@Slf4j
@Component
public class SendMessageJob extends QuartzJobBean {
@Autowired
private ScheduleService scheduleService;
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
Trigger trigger = jobExecutionContext.getTrigger();
JobDetail jobDetail = jobExecutionContext.getJobDetail();
JobDataMap jobDataMap = jobDetail.getJobDataMap();
String data = jobDataMap.getString("data");
log.info("Timed message operation in station: {}",data);
// Delete triggers and tasks after completionscheduleService.cancelScheduleJob(trigger.getKey().getName()); }}Copy the code
/** * Created by macro on 2020/9/29. */
@Slf4j
@Component
public class CronProcessJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
JobDetail jobDetail = jobExecutionContext.getJobDetail();
JobDataMap jobDataMap = jobDetail.getJobDataMap();
String data = jobDataMap.getString("data");
log.info("CRON expression task execution: {}",data); }}Copy the code
- Finally, create the task scheduling related interface and call the task scheduling business class.
/** * Created by macro on 2020/9/29. */
@API (tags = "ScheduleController", description = "Interface for scheduling tasks ")
@RestController
@RequestMapping("/schedule")
public class ScheduleController {
@Autowired
private ScheduleService scheduleService;
@apiOperation (" Send emails regularly ")
@PostMapping("/sendEmail")
public CommonResult sendEmail(@RequestParam String startTime,@RequestParam String data) {
Date date = DateUtil.parse(startTime, DatePattern.NORM_DATETIME_FORMAT);
String jobName = scheduleService.scheduleFixTimeJob(SendEmailJob.class, date, data);
return CommonResult.success(jobName);
}
@apiOperation (" Timed send station message ")
@PostMapping("/sendMessage")
public CommonResult sendMessage(@RequestParam String startTime,@RequestParam String data) {
Date date = DateUtil.parse(startTime, DatePattern.NORM_DATETIME_FORMAT);
String jobName = scheduleService.scheduleFixTimeJob(SendMessageJob.class, date, data);
return CommonResult.success(jobName);
}
@apiOperation (" Scheduling tasks via CRON expressions ")
@PostMapping("/scheduleJob")
public CommonResult scheduleJob(@RequestParam String cron, @RequestParam String data) {
String jobName = scheduleService.scheduleJob(CronProcessJob.class, cron, data);
return CommonResult.success(jobName);
}
@apiOperation (" Cancel scheduled task ")
@PostMapping("/cancelScheduleJob")
public CommonResult cancelScheduleJob(@RequestParam String jobName) {
Boolean success = scheduleService.cancelScheduleJob(jobName);
returnCommonResult.success(success); }}Copy the code
Run the test
- Call timed mail interface test;
- Task execution information is printed on the console after the task arrives.
11:23:00 2020-09-30. 10160-035 the INFO [] eduler_Worker - 1 com. Macro. Mall. Tiny. Job. SendEmailJob: operation: timing to send mail to send emailCopy the code
- The CRON expression is used to start a scheduled task, starting from 0s and executing it every 10s.
- The console prints the task execution information every 10 seconds.
The 2020-09-30 11:26:30. 10160-024 the INFO [eduler_Worker - 2] com. Macro. Mall. Tiny. Job. CronProcessJob: CRON expressions perform tasks: CRON news contents 11:26:40 2020-09-30. 10160-025 the INFO/eduler_Worker - 3 com. Macro. Mall. Tiny. Job. CronProcessJob: CRON expressions perform tasks: CRON news contents 11:26:50 2020-09-30. 10160-017 the INFO [eduler_Worker - 4] com. Macro. Mall. Tiny. Job. CronProcessJob: CRON expressions perform tasks: CRON news contents 11:27:00 2020-09-30. 10160-023 the INFO [eduler_Worker - 5] com. Macro. Mall. Tiny. Job. CronProcessJob: CRON expressions perform tasks: CRON news contents 11:27:10 2020-09-30. 10160-019 the INFO [eduler_Worker - 6] com. Macro. Mall. Tiny. Job. CronProcessJob: CRON expression task execution: CRON message contentCopy the code
- We can return it by starting the task
jobName
To cancel the scheduled task, the scheduled task will not be executed after the call is successful.
The resources
The official document: www.quartz-scheduler.org/documentati…
Project source code address
Github.com/macrozheng/…
In this paper, making github.com/macrozheng/… Already included, welcome everyone Star!