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

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Einführung in Jasypt Jasypt ist eine Java-Bibliothek, die es einem Entwickler ermöglicht, seinem Projekt mit minimalem Aufwand grundlegende Verschlüsselungsfunktionen hinzuzufügen und kein tiefes Verständnis der Funktionsweise der Verschlüsselung erfordert. standardbasierte Verschlüsselungstechnologie. Passwörter, Text, Zahlen, Binärdateien verschlüsseln ... Geeignet für die Integration in Spring-basierte Anwendungen, offene API, zur Verwendung mit jedem JCE-Anbieter ... Fügen Sie die folgende Abhängigkeit hinzu: com.github.ulisesbocchiojasypt-spring-boot-starter2 Die Vorteile von Jasypt schützen unsere Systemsicherheit. Selbst wenn der Code durchgesickert ist, kann die Datenquelle garantiert werden.

Nutzungsszenario 1. Die Bestellung wurde erfolgreich aufgegeben, die Zahlung erfolgte jedoch nicht innerhalb von 30 Minuten. Die Zahlung ist abgelaufen und die Bestellung wurde automatisch storniert. 2. Die Bestellung wurde unterzeichnet und es wurde 7 Tage lang keine Bewertung durchgeführt. Wenn die Bestellung abläuft und nicht ausgewertet wird, wird die Bestellung standardmäßig positiv bewertet. Wenn der Händler die Bestellung innerhalb von 5 Minuten nicht erhält, wird die Bestellung abgebrochen Es wird eine SMS-Erinnerung gesendet ... Für Szenarien mit langen Verzögerungen und geringer Echtzeitleistung können wir die Aufgabenplanung verwenden, um eine regelmäßige Abfrageverarbeitung durchzuführen. Zum Beispiel: xxl-job Heute werden wir auswählen

1. Redis implementiert das Prinzip der verteilten Sperren und warum verteilte Sperren erforderlich sind. Bevor über verteilte Sperren gesprochen wird, muss erläutert werden, warum verteilte Sperren erforderlich sind. Das Gegenteil von verteilten Sperren sind eigenständige Sperren. Wenn wir Multithread-Programme schreiben, vermeiden wir Datenprobleme, die durch den gleichzeitigen Betrieb einer gemeinsam genutzten Variablen verursacht werden. Normalerweise verwenden wir eine Sperre, um die Richtigkeit der gemeinsam genutzten Variablen sicherzustellen Die gemeinsam genutzten Variablen liegen im gleichen Prozess. Wenn es mehrere Prozesse gibt, die gleichzeitig eine gemeinsam genutzte Ressource betreiben müssen, wie können sie sich dann gegenseitig ausschließen? Heutige Geschäftsanwendungen sind in der Regel Microservice-Architekturen, was auch bedeutet, dass eine Anwendung mehrere Prozesse bereitstellen muss. Wenn mehrere Prozesse dieselbe Datensatzzeile in MySQL ändern müssen, ist eine Verteilung erforderlich, um fehlerhafte Daten zu vermeiden wird zu diesem Zeitpunkt eingeführt. Der Stil ist gesperrt. Punkte erreichen wollen

Springboot liest die Datei, kann aber nach dem Packen in ein JAR-Paket nicht auf die neueste Entwicklung zugreifen. Es gibt eine Situation, in der Springboot die Datei nach dem Packen in ein JAR-Paket nicht lesen kann ist ungültig und kann nur über den Stream gelesen werden. Die Datei befindet sich unter resources publicvoidtest(){Listnames=newArrayList();InputStreamReaderread=null;try{ClassPathResourceresource=newClassPathResource("name.txt");Input

SpringBoot und SpringMVC sind beide häufig verwendete Frameworks in der Java-Entwicklung, es gibt jedoch einige offensichtliche Unterschiede zwischen ihnen. In diesem Artikel werden die Funktionen und Verwendungsmöglichkeiten dieser beiden Frameworks untersucht und ihre Unterschiede verglichen. Lassen Sie uns zunächst etwas über SpringBoot lernen. SpringBoot wurde vom Pivotal-Team entwickelt, um die Erstellung und Bereitstellung von Anwendungen auf Basis des Spring-Frameworks zu vereinfachen. Es bietet eine schnelle und einfache Möglichkeit, eigenständige, ausführbare Dateien zu erstellen

Wenn Springboot + Mybatis-plus keine SQL-Anweisungen zum Hinzufügen mehrerer Tabellen verwendet, werden die Probleme, auf die ich gestoßen bin, durch die Simulation des Denkens in der Testumgebung zerlegt: Erstellen Sie ein BrandDTO-Objekt mit Parametern, um die Übergabe von Parametern an den Hintergrund zu simulieren dass es äußerst schwierig ist, Multi-Table-Operationen in Mybatis-plus durchzuführen. Wenn Sie keine Tools wie Mybatis-plus-join verwenden, können Sie nur die entsprechende Mapper.xml-Datei konfigurieren und die stinkende und lange ResultMap konfigurieren Schreiben Sie die entsprechende SQL-Anweisung. Obwohl diese Methode umständlich erscheint, ist sie äußerst flexibel und ermöglicht es uns

1. Passen Sie den RedisTemplate1.1-Standard-Serialisierungsmechanismus an. Die API-basierte Redis-Cache-Implementierung verwendet die RedisTemplate-Vorlage für Daten-Caching-Vorgänge. Öffnen Sie hier die RedisTemplate-Klasse und zeigen Sie die Quellcodeinformationen der Klasse publicclassRedisTemplateextendsRedisAccessorimplementsRedisOperations an. Schlüssel deklarieren, verschiedene Serialisierungsmethoden des Werts, der Anfangswert ist leer @NullableprivateRedisSe

In Projekten werden häufig einige Konfigurationsinformationen benötigt. Diese Informationen können in der Testumgebung und in der Produktionsumgebung unterschiedliche Konfigurationen haben und müssen möglicherweise später basierend auf den tatsächlichen Geschäftsbedingungen geändert werden. Wir können diese Konfigurationen nicht fest im Code codieren. Am besten schreiben Sie sie in die Konfigurationsdatei. Sie können diese Informationen beispielsweise in die Datei application.yml schreiben. Wie erhält oder verwendet man diese Adresse im Code? Es gibt 2 Methoden. Methode 1: Wir können den Wert, der dem Schlüssel in der Konfigurationsdatei (application.yml) entspricht, über den mit @Value versehenen Wert erhalten. Diese Methode eignet sich für Situationen, in denen es relativ wenige Mikrodienste gibt: Tatsächlich Projekte, wenn das Geschäft kompliziert ist, Logik
