Prefacio
Para garantizar una alta disponibilidad y una alta concurrencia de las aplicaciones, generalmente se implementan múltiples nodos; Para las tareas de tiempo, si cada nodo realiza sus propias tareas de tiempo, consume recursos del sistema, por un lado.
Por otro lado, algunas tareas se ejecutan varias veces, lo que puede causar problemas lógicos de aplicación, por lo que se necesita un sistema de programación distribuido para coordinar cada nodo para realizar tareas de tiempo.
Spring integra cuarzo
Quartz es un sistema de programación de tareas maduras. La primavera es compatible con cuarzo para un fácil desarrollo. Veamos cómo integrarlo:
1. Archivo de dependencia de Maven
<Spendencies> <Spendency> <MoupRid> org.springframework </proupid> <artifactid> spring-core </artifactid> <verserse> 4.3.5.release </versevers> </dependency> <ependency> <grupoD> org.springframework </groupid> <artifactid> springcontext-support </artifactid> <loture> </pendency> <epardency> <uproupid> org.springframework </proupid> <artifactid> spring-tx </artifactid> <versers> 4.3.5.release </ververy> </dependency> <ependency> <proupid> org.springframework </proupid> <artifactid> spring-jdbc </artiFactid> <verserse. </pendency> <pendency> <uproupid> org.quartz-scheduler </groupid> <artifactid> quartz </arfactid> <versión> 2.2.3 </versión> </pendency> <sependency> <proupid> mysql </groupId> <artifactid> mysql-connector-java </artifactid> <ververy> <verserse.29.29.29.29> </pendency> </dependencias>
Las principales son bibliotecas relacionadas con la primavera, bibliotecas de cuarzo y bibliotecas de controladores MySQL. Nota: La programación distribuida requiere uso de la base de datos, y MySQL se selecciona aquí;
2. Configurar el trabajo
Hay dos formas de configurar trabajos, a saber: MethodinvokingJobDetailFactoryBean y JobDetailFactoryBean
2.1MethodinvokingJobdetailFactoryBean
Cuando desea llamar a un método de un frijol específico, la configuración específica es la siguiente:
<bean id = "firstTask"> <Property name = "TargetObject" ref = "FirstService" /> <Property Name = "TargetMethod" Value = "Service" /> < /bea>
2.2JobdetailFactoryBean
Este método es más flexible y puede establecer los parámetros de paso, como sigue:
<bean id = "firstTask"> <Property name = "JobClass" value = "zh.maven.squartz.task.firsttask"/> <propiedad name = "jobdatamap"> <s map> <inying key = "firstService" value-ref = "firstService"/> </s map> </propers> </ beay>
La clase de tareas definida por JobClass hereda el cuarzo y implementa el método Ejecutal; JobDatamap se usa para pasar datos al trabajo
3. Configure los desencadenantes utilizados para la programación
También se proporcionan dos tipos de gatillo: SimpleTriggerFactoryBean y CrontriggerFactoryBean
Concéntrese en CrontriggerFactoryBean, este tipo es más flexible, como sigue:
<bean id = "firstCronTrigger"> <Property name = "JobDetail" ref = "FirstTask" /> <Property Name = "Cronexpression" Value = "0/5 * *? * *" /> </lebre>
JobDetail especifica el trabajo configurado en el paso 2, y la cronexpresión está configurada para ejecutar el trabajo cada 5 segundos;
4. Configure el SchedulerFactoryBean del planificador de cuarzo
También hay dos métodos: memoria Ramjobstore y métodos de base de datos
4.1 Memoria Ramjobstore
La información relacionada con el trabajo se almacena en la memoria, y cada nodo almacena la suya, se aísla entre sí y se configura de la siguiente manera:
<Bean> <Property Name = "ARGIGTERS"> <LIST> <ref Bean = "FirstCronTrigger"/> </list> </Property> </Bean>
4.2 Método de la base de datos
La información relevante del trabajo se almacena en la base de datos. Todos los nodos comparten la base de datos. Cada nodo se comunica a través de la base de datos para garantizar que un trabajo solo se ejecute en un nodo al mismo tiempo.
Si un nodo falla, el trabajo se asignará a otros nodos para su ejecución. La configuración específica es la siguiente:
<bean id = "dataSource" destruye-method = "Close"> <Property Name = "DriverClass" value = "com.mysql.jdbc.driver" /> <propiedad name = "jdbcurl" valor = "jdbc: mysql: // localhost: 3306 /quartz" /> <name de la propiedad = "usuary =" root " /> <n. </bean> <Bean> <Property name = "dataSource" ref = "dataSource"/> <Property name = "configlocation" value = "classpath: cuarzo.properties"/> <propiedad name = "desgarradoras"> <list> <ref bean = "firstCrontrigger"/> </list> </bean>
DataSource se utiliza para configurar fuentes de datos e información relacionada con la tabla de datos. Puede descargar el paquete GZ desde el sitio web oficial. El archivo SQL está debajo de la ruta: Docs/DBTables, que proporciona el archivo SQL para la base de datos principal;
El archivo Quartz.Properties configurado en configLocation se encuentra en el paquete Org.quartz de Quartz.jar, que proporciona algunos datos predeterminados, como org.quartz.jobstore.class
org.quartz.jobstore.class: org.quartz.simpl.ramjobstore
Aquí debe copiar cuarzo. Properties y hacer algunas modificaciones. Las modificaciones específicas son las siguientes:
org.quartz.scheduler.instanceid: autoorg.quartz.jobstore.class: org.quartz.impl.jdbcjobstore.jobstoretxorg.quartz.jobstore.isclustered: trueorg.quartz.jobstore.clustercheckininterval: 1000
5. Categorías relacionadas
Public Class FirstTask extiende Quartzjobbean {Primer servicio privado FirstService; @Override Protected Void ExecuteInternal (JobExecutionContext Context) lanza JobExecutionException {FirstService.Service (); } public void setFirstService (FirstService FirstService) {this.FirstService = FirstService; }}FirstTask hereda el cuarzo, implementa el método de ejecución instantánea y llama al servicio
Public Class FirstService implementa serializable {privado estático final Long SerialVersionUid = 1L; Public void Service () {System.out.println (new SimpleDateFormat ("yyymmdd hh: mm: ss"). format (new date ()) + "--- inicio de primer servicio"); intente {Thread.sleep (2000); } catch (InterruptedException e) {E.PrintStackTrace (); } System.out.println (nuevo SimpleDateFormat ("yyymmdd hh: mm: ss"). Format (new date ()) + "--- final de primer servicio"); }}FirstService debe proporcionar una interfaz de serialización porque debe guardarla en la base de datos;
Public Class App {public static void main (string [] args) {abstractApplicationContext context = new ClassPathXMLAplaPlicationContext ("Quartz.xml"); }}La clase principal se utiliza para cargar el archivo de configuración de cuarzo;
Prueba de programación distribuida
1. Inicie la aplicación dos veces al mismo tiempo y observe el registro:
20180405 14:48:10 --- Iniciar primer servicio
20180405 14:48:12 ---- End Firstservice
20180405 14:48:15 --- Comienza el primer servicio
20180405 14:48:17 ---- End FirstService
Entre ellos, A1 tiene salida de registro, pero A2 no; Cuando se detiene A1, A2 tiene salida de registro;
2. Agregue nuevos trabajos y cree nuevos: SecondTask y SecondService respectivamente. Agregue archivos de configuración relevantes al mismo tiempo. Inicie la aplicación dos veces y observe el registro:
El registro A1 es el siguiente:
20180405 15:03:15 --- Comienza el primer servicio
20180405 15:03:15 --- Iniciar segundo servicio
20180405 15:03:17 ---- End FirstService
20180405 15:03:17 --- Fin de segundo servicio
20180405 15:03:20 --- Comienza el primer servicio
20180405 15:03:22 ---- End FirstService
20180405 15:03:25 --- Iniciar primer servicio
20180405 15:03:27 ---- End Firstservice
El registro A2 es el siguiente:
20180405 15:03:20 --- Iniciar segundo servicio
20180405 15:03:22 --- Fin de segundo servicio
20180405 15:03:25 --- Iniciar segundo servicio
20180405 15:03:27 --- Fin de segundo servicio
Se puede encontrar que tanto A1 como A2 tienen tareas de ejecución, pero la misma tarea solo se ejecutará en un nodo al mismo tiempo, y es posible asignarse a otros nodos después de que se complete la ejecución;
3. Si el tiempo de intervalo es menor que el tiempo de ejecución de la tarea, por ejemplo, aquí se cambia a dormir (6000)
El registro A1 es el siguiente:
20180405 15:14:40 --- Comienza el primer servicio
20180405 15:14:45 --- Comienza el primer servicio
20180405 15:14:46 ---- End FirstService
20180405 15:14:50 --- Iniciar primer servicio
20180405 15:14:50 --- Iniciar segundo servicio
20180405 15:14:51 --- finalizar el primer servicio
El registro A2 es el siguiente:
20180405 15:14:40 --- Iniciar segundo servicio
20180405 15:14:45 --- Iniciar segundo servicio
20180405 15:14:46 --- Fin de segundo servicio
20180405 15:14:51 --- Fin de segundo servicio
El intervalo es de 5 segundos, mientras que la ejecución de la tarea toma 6 segundos. Al observar el registro, puede encontrar que la tarea aún no ha terminado y que ha comenzado una nueva tarea. Esta situación puede causar problemas lógicos en la aplicación, que en realidad es la cuestión de si la tarea puede soportar serial;
4. @DisallowConcurrentExecution La anotación garantiza la serialización de las tareas
Agregue la anotación de @DisallowConcurrentExecution en FirstTask y SecondTask respectivamente, y los resultados del registro son los siguientes:
El registro A1 es el siguiente:
20180405 15:32:45 --- Comienza el primer servicio
20180405 15:32:51 --- finalizar el primer servicio
20180405 15:32:51 --- Comienza el primer servicio
20180405 15:32:51 --- Iniciar segundo servicio
20180405 15:32:57 ---- End FirstService
20180405 15:32:57 --- Fin de segundo servicio
20180405 15:32:57 --- Comienza el primer servicio
20180405 15:32:57 --- Iniciar segundo servicio
El registro A2 es el siguiente:
20180405 15:32:45 --- Iniciar segundo servicio
20180405 15:32:51 --- Fin de segundo servicio
Al observar los registros, puede encontrar que la tarea solo iniciará una nueva tarea después del final y se dará cuenta de la serialización de la tarea;
Resumir
Este artículo tiene como objetivo tener una comprensión intuitiva de la programación distribuida de primavera+cuarzo y resolver el problema a través del uso real. Por supuesto, puede haber muchas preguntas, como cómo se programa, qué sucederá si la base de datos se cuelga, etc., y se necesita una comprensión más profunda.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.