Heim > Java > JavaBase > Hauptteil

springboot+quartz implementiert geplante Aufgaben dauerhaft

Guanhui
Freigeben: 2020-07-27 18:33:19
nach vorne
2935 Leute haben es durchsucht

springboot+quartz implementiert geplante Aufgaben dauerhaft

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("执行定时任务");
 }

}
Nach dem Login kopieren

######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>
Nach dem Login kopieren

Quarz

  • Scheduler
  • Starten Sie den Trigger, um die Aufgabe auszuführen
  • Trigger-Trigger

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
Nach dem Login kopieren

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
Nach dem Login kopieren

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";

}
Nach dem Login kopieren

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";
  }
Nach dem Login kopieren

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
Nach dem Login kopieren

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;
 }
}
Nach dem Login kopieren

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();
 }
}
Nach dem Login kopieren

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;
 }
}
Nach dem Login kopieren

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 {
 
 }
}
Nach dem Login kopieren

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 &#39;编号&#39;,
 `job_name` varchar(50) DEFAULT &#39;&#39; COMMENT &#39;任务名&#39;,
 `job_group` varchar(50) DEFAULT &#39;&#39; COMMENT &#39;任务组名称&#39;,
 `job_desc` varchar(255) DEFAULT &#39;&#39; COMMENT &#39;job描述&#39;,
 `cron` varchar(50) DEFAULT &#39;&#39; COMMENT &#39;cron表达式&#39;,
 `status` tinyint(1) DEFAULT &#39;0&#39; COMMENT &#39;状态&#39;,
 `url` varchar(255) DEFAULT &#39;&#39; COMMENT &#39;请求地址&#39;,
 `param` varchar(255) DEFAULT &#39;&#39; COMMENT &#39;参数&#39;,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8;
Nach dem Login kopieren

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 "开始任务的时候发生了错误,请检查日志";
 }
Nach dem Login kopieren

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!

Verwandte Etiketten:
Quelle:jb51.net
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!