Dieser Artikel stellt Springboot + Quartz vor, um geplante Aufgaben dauerhaft umzusetzen. Die Details sind wie folgt:
Es ist ziemlich lang, aber wer Geduld hat, kann es Immer Nachdem ich die endgültige Antwort erhalten habe, verwende ich Quarz zum ersten Mal für eine geplante Aufgabe. Ich entschuldige mich für etwaige Mängel.
Zuallererst
Es ist relativ einfach, geplante Aufgaben im Springboot-Projekt zu erledigen. Der einfachste Weg, es zu implementieren, ist die Verwendung von **@Scheduled-Annotation. Verwenden Sie dann @EnableScheduling** für die Anwendungsstartklasse, um geplante Aufgaben zu aktivieren.
Beispiel
@SpringBootApplication @EnableScheduling public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } // cron为每秒执行一次 @Scheduled(cron = "* * * * * ?") public void print(){ System.out.println("执行定时任务"); } }
######Ergebnis
Geplante Aufgabe ausführen
Geplante Aufgabe ausführen
Geplante Aufgabe ausführen
Geplant ausführen Aufgabe Aufgabe
Eine geplante Aufgabe ausführen
Eine geplante Aufgabe ausführen
Eine geplante Aufgabe ausführen
Eine geplante Aufgabe ausführen
Einfache geplante Aufgaben können auf diese Weise erledigt werden, cron Ausdruck Das Ergebnis ist das Intervall zwischen Aufgabenausführungen.
Allerdings
In der tatsächlichen Entwicklung haben wir möglicherweise viele Aufgaben und müssen einzelne/alle Aufgaben manuell ausführen, z. B. Hinzufügen, Öffnen , Stopp, Fortfahren und andere Vorgänge. Dann erscheint Quarz zusammen mit der Hintergrundmusik von „Qianniu Class B…“.
Quarz
Integrieren Sie die drei Elemente von
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
Quarz
wird verwendet, um Job-(Aufgaben-)Triggerbedingungen, Triggerzeit, Triggerintervall, Beendigungszeit usw. zu definieren.
Aufgabenjob
Spezifischer Aufgabeninhalt, der ausgeführt werden soll
Verwendung
Für die Verwendung von Quarz ist eine Konfigurationsdatei erforderlich. Die Datei quartz.properties befindet sich im Paket org.quartz des Pakets quartz.properties
# Default Properties file for use by StdSchedulerFactory # to create a Quartz Scheduler Instance, if a different # properties file is not explicitly specified. # # 名字 org.quartz.scheduler.instanceName: DefaultQuartzScheduler org.quartz.scheduler.rmi.export: false org.quartz.scheduler.rmi.proxy: false org.quartz.scheduler.wrapJobExecutionInUserTransaction: false # 实例化ThreadPool时,使用的线程类为SimpleThreadPool org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool # 线程总个数 org.quartz.threadPool.threadCount: 10 # 线程的优先级 org.quartz.threadPool.threadPriority: 5 org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true org.quartz.jobStore.misfireThreshold: 60000 # 持久化方式,默认持久化在内存中,后面我们使用db的方式 org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
Persistente Quarzaufgaben für die Datenbank erfordern einige offiziell definierte Datenbanken Tabelle, die SQL-Datei der Tabelle befindet sich im JAR-Paket von Quartz
Koordinaten org.quartz.impl.jdbcjobstore. Sie können sehen, dass darin viele SQL-Dateien enthalten sind, einschließlich verschiedener Datenbanken MySQL muss die SQL-Anweisung nicht manuell ausführen, wir werden sie später beim Starten des Projekts automatisch initialisieren.
Erstellen Sie unsere eigene Eigenschaftendatei
# 实例化ThreadPool时,使用的线程类为SimpleThreadPool org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool # threadCount和threadPriority将以setter的形式注入ThreadPool实例 # 并发个数 org.quartz.threadPool.threadCount=10 # 优先级 org.quartz.threadPool.threadPriority=5 org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true org.quartz.jobStore.misfireThreshold=5000 #持久化使用的类 org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX #数据库中表的前缀 org.quartz.jobStore.tablePrefix=QRTZ_ #数据源命名 org.quartz.jobStore.dataSource=qzDS #qzDS 数据源,我们使用hikaricp,默认的是c3p0 org.quartz.dataSource.qzDS.provider=hikaricp org.quartz.dataSource.qzDS.driver=com.mysql.cj.jdbc.Driver org.quartz.dataSource.qzDS.URL=jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8 org.quartz.dataSource.qzDS.user=root org.quartz.dataSource.qzDS.password=123456 org.quartz.dataSource.qzDS.maxConnections=10
Da wir nicht den Standardverbindungspool verwenden, erkunden wir ihn und besorgen uns den Quellcode! Unter diesem Paket: org.quartz.utils gibt es einen PoolingConnectionProvider, den Quellcode des Verbindungspoolanbieters
public interface PoolingConnectionProvider extends ConnectionProvider { /** The pooling provider. */ String POOLING_PROVIDER = "provider"; /** The c3p0 pooling provider. */ String POOLING_PROVIDER_C3P0 = "c3p0"; /** The Hikari pooling provider. */ String POOLING_PROVIDER_HIKARICP = "hikaricp"; }
Dann implementiert die HikariCpPoolingConnectionProvider-Klasse PoolingConnectionProvider. Wir können in StdSchedulerFactory unter org.quartz.impl nach c3p0 suchen, um
if(poolingProvider != null && poolingProvider.equals(PoolingConnectionProvider.POOLING_PROVIDER_HIKARICP)) { cpClass = "org.quartz.utils.HikariCpPoolingConnectionProvider"; } else { cpClass = "org.quartz.utils.C3p0PoolingConnectionProvider"; }
zu finden. Den Rest zu recherchieren ist nicht so schwierig oder langweilig wie gedacht (das gefällt mir nicht). Lesen Sie entweder den Quellcode) ), aber dieser Quellcode scheint ein kleines Erfolgserlebnis zu haben.
Gehen Sie zurück zum Themenkanal und konfigurieren Sie application.yml
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver password: 123456 url: jdbc:mysql://localhost:3306/quartz?characterEncoding=UTF8&useSSL=false&serverTimezone=GMT%2B8 username: root quartz: jdbc: initialize-schema: always job-store-type: jdbc
initialize-schema: Always Initialisieren Sie bei jedem Start des Projekts immer die Datenbanktabelle und erstellen Sie automatisch den Schlüsselteil der Tabelle Der Prozess besteht darin, zuerst die Datenbanktabelle zu löschen und erneut zu erstellen. Wenn die Tabelle nicht vorhanden ist, wird eine Ausnahme ausgelöst, die sich jedoch nicht auf die nachfolgend generierte Tabelle auswirkt, da die Tabelle bereits vorhanden ist existiert, wird die Ausnahme nicht ausgelöst job-store-type: jdbc Es ist der Task-Persistenztyp
Wir müssen möglicherweise Spring-Objekte in den Job einfügen, er kann nicht eingefügt werden .
/** * @author: taoym * @date: 2020/6/4 11:32 * @desc: 一定要自定义JobFactory重写SpringBeanJobFactory的createJobInstance方法,否则在job中是获取不到spring容器中的bean的 */ @Component public class JobFactory extends SpringBeanJobFactory { @Autowired private AutowireCapableBeanFactory beanFactory; /** * 这里覆盖了super的createJobInstance方法,对其创建出来的类再进行autowire */ @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { Object jobInstance = super.createJobInstance(bundle); beanFactory.autowireBean(jobInstance); return jobInstance; } }
Quarz-Konfigurationsdatei erstellen
@Configuration public class QuartzConfig { @Autowired private JobFactory jobFactory; /** * 读取quartz.properties 文件 * 将值初始化 * * @return */ @Bean public Properties quartzProperties() throws IOException { PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean(); propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties")); propertiesFactoryBean.afterPropertiesSet(); return propertiesFactoryBean.getObject(); } @Bean public SchedulerFactoryBean schedulerFactoryBean() throws IOException { SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); schedulerFactoryBean.setJobFactory(jobFactory); schedulerFactoryBean.setQuartzProperties(quartzProperties()); return schedulerFactoryBean; } /** * 初始化监听器 * * @return */ @Bean public QuartzInitializerListener executorListener() { return new QuartzInitializerListener(); } @Bean(name = "scheduler") public Scheduler scheduler() throws IOException { return schedulerFactoryBean().getScheduler(); } }
Trigger-Komponente erstellen
public class TriggerComponent { /** * @author: taoym * @date: 2020/6/1 10:35 * @desc: 构建cron触发器 */ public static Trigger cronTrigger(String cron) { CronTrigger cronTrigger = TriggerBuilder.newTrigger() .withSchedule(CronScheduleBuilder.cronSchedule(cron).withMisfireHandlingInstructionDoNothing()) .build(); return cronTrigger; } public static Trigger cronTrigger(String cron, JobDataMap jobDataMap) { CronTrigger cronTrigger = TriggerBuilder.newTrigger() .withSchedule(CronScheduleBuilder.cronSchedule(cron).withMisfireHandlingInstructionDoNothing()) .usingJobData(jobDataMap) .build(); return cronTrigger; } }
Verwenden Sie einfach diese Komponente, um den Trigger zu erhalten.
Aufgabe erstellen
@DisallowConcurrentExecution public class TestJob extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { } }
jobExecutionContext Hier können Sie die Aufgabengruppe, den Aufgabennamen, die Triggergruppe, den Triggernamen, die Jobdetails und andere Informationen abrufen. Diese Anmerkung soll ermöglichen, dass dieselbe Instanz (Jobdetail) nur in einem einzigen Thread ausgeführt wird. Es versteht sich, dass job eine Schnittstelle ist, jobdetail eine Implementierungsklasse ist und a eine der Implementierungsklassen ist. Es dauert 100 Sekunden, um eine bestimmte Operation auszuführen, und der von Ihnen angegebene Timer führt alle 50 Sekunden eine Operation aus Zur Hälfte der Ausführung muss ein weiterer Thread zur Ausführung gestartet werden. Die Verwendung von DisallowConcurrentExecution bedeutet, dass a den Thread nicht öffnen und dann den aktuellen Vorgang ausführen darf, wenn a den Vorgang nicht abgeschlossen hat. Ich weiß nicht, ob meine Beschreibung leicht verständlich ist!
Erstellen Sie nach Bedarf Ihre eigene Aufgabenliste. Ich verwende geplante Aufgaben, um Crawler (kleine Crawler) zu erstellen.
CREATE TABLE `quartz_job` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '编号', `job_name` varchar(50) DEFAULT '' COMMENT '任务名', `job_group` varchar(50) DEFAULT '' COMMENT '任务组名称', `job_desc` varchar(255) DEFAULT '' COMMENT 'job描述', `cron` varchar(50) DEFAULT '' COMMENT 'cron表达式', `status` tinyint(1) DEFAULT '0' COMMENT '状态', `url` varchar(255) DEFAULT '' COMMENT '请求地址', `param` varchar(255) DEFAULT '' COMMENT '参数', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8;
Wenn wir Aufgaben hinzufügen, kümmern wir uns nicht um Quarz, sondern fügen die Aufgaben einfach ein die Datenbank. Keine Panik, er wird später nützlich sein. Diese Tabelle muss hinzugefügt, gelöscht, geändert und überprüft werden. Wir werden die Aufgabenliste im System abfragen und eine einzelne oder alle Aufgaben auswählen, um mit der Ausführung zu beginnen
Führen Sie die Aufgabe aus
@Resource private QuartzJobMapper quartzJobMapper; @Autowired private Scheduler scheduler; @Override public String start(Integer id) { JobDataMap jobDataMap = new JobDataMap(); jobDataMap.put(k,v); QuartzJob quartzJob = quartzJobMapper.selectByPrimaryKey(id); JobKey jobKey = JobKey.jobKey(quartzJob.getJobName(), quartzJob.getJobGroup()); jobDetail = JobBuilder.newJob(TestJob.class).withIdentity(jobKey).storeDurably().build(); Trigger trigger = TriggerComponent.cronTrigger(quartzJob.getCron(), jobDataMap); try { scheduler.scheduleJob(jobDetail, trigger); quartzJobMapper.updateStatus(true, id); return "开始任务执行成功"; } catch (SchedulerException se) { log.info("开始任务的时候发生了错误"); } return "开始任务的时候发生了错误,请检查日志"; }
Abschließend Ich habe es gemäß dem Inhalt dieses Tutorials eingefügt. Sobald der Code übergeben wurde, kann er normal ausgeführt werden.
Empfohlenes Tutorial: „PHP“
Das obige ist der detaillierte Inhalt vonspringboot+quartz implementiert geplante Aufgaben dauerhaft. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!