Spring Batch
Introducción
En el mundo de la informática, a menudo separamos el procesamiento en tres familias principales: procesamiento en tiempo real, procesamiento por batchs o lotes y una familia de procesamiento híbrido, que es una composición de los dos primeros, como el streaming, que procesa grandes volúmenes en tiempo real.
En la actualidad, los batchs son el resultado de programas de migración y modernización de antiguos programas de procesamiento masivo convencional. También se utilizan para el Big Data en aplicaciones modernas.
En general, intentamos prescindir de batchs y procesamos los datos sobre la marcha o en la aplicación, a través de minibatchs o un programador Spring @Scheduled. En algunos casos, los batchs son inevitables.
En general, el procesamiento por batchs requiere acceso completo y exclusivo a las bases de datos, lo que implica detener el procesamiento con interfaces hombre-máquina. En la era de la globalización, se hace imposible cerrar el acceso a las aplicaciones durante el período de los batchs.
En los primeros días de la informática, el procesamiento a menudo se realizaba con Mainframes. Hay que saber que un Mainframe es un servidor muy grande (los grandes pueden alcanzar los 80 000 MIPS) hiperoptimizado para dos cosas: permite a un gran número de usuarios introducir datos durante el día a través de un terminal para procesarlos en masa durante la noche....
Arquitectura de un batch
La aplicación Spring Batch se descompone en varias partes. Una parte técnica se codifica en forma de framework configurable, y una parte reservada para el procesamiento específico relacionado con la parte funcional es personalizable.
El batch se compone de un lanzador: el Job launcher, que lanza los trabajos llamados Jobs, compuestos por pasos denominados Steps. Todo se traza en una base de datos a través del Repository.
Los listeners también permiten la llamada de código a través de las notificaciones sobre el ciclo de vida de los trabajos y las etapas.
Cada etapa (Job) se divide en tres partes:
El Reader, que lee los datos denominados Items como entrada; el Processor, que procesa estos datos, y el Writer, que escribe los datos como salida.
Ejemplo de Spring Batch versión 4
Ahora codificamos un ejemplo de un pequeño batch para ilustrar cómo funciona Spring Batch.
Dependencia Maven:
<dependencies>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
</dependencies>
Vamos a crear una clase main para ejecutar el batch:
@EnableBatchProcessing
@SpringBootApplication
public class Main {
public static void main(String [] args) {
System.exit(SpringApplication.exit(SpringApplication.run(
BatchConfiguration.class, args)));
}
}
Vamos a crear una clase de configuración para configurar el batch con un job que contiene un Step. Un Job es un conjunto de Steps y cada uno realiza una operación elemental.
@Configuration
public class BatchConfiguration...
Cargador H2 desde un CSV
Codificamos un segundo ejemplo que muestra cómo cargar un archivo CSV en una base de datos H2. El ejemplo utiliza un Reader (unidad de lectura) para acceder al contenido del archivo CSV. Utiliza el FlatFileItemReader, para el que indicamos el formato de una línea a través de la declaración: FlatFileItemReader<Comunidad> reader = newFlatFile ItemReader<Comunidad>();. La unidad de lectura utiliza un LineMapper para descodificar una línea en el archivo CSV. Tenemos un Writter para escribir en la base de datos H2. Se trata de un JdbcBatchItemWriter. Almacena una fila de datos en H2. Tenemos un ItemProcessor que procesa una fila de datos. Aquí, nuestro procesador pone en mayúsculas la información que lee del archivo CSV. Tenemos un Job que encadena etapas llamadas Step. Nuestro Step step1 lee la línea en el CSV, la procesa con el processor y la guarda en H2.
El lanzador:
@SpringBootApplication
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
La clase Comunidad:
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Comunidad {
private String codigo;
private String nombre;
}
Configuración por batchs:
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Autowired
public DataSource dataSource;
// tag::readerwriterprocessor[]
@Bean
public FlatFileItemReader<Comunidad> reader() { ...
Dependencias Spring Batch 3 y 4
Spring Batch 4 ha revisado todas sus dependencias respecto a Spring Batch 3 y requiere Java 8+ y Spring 5+.
Otras novedades de la versión 4
Hay builders para ItemReader, ItemProcessor y ItemWriter, así como una variedad de builders para simplificar la escritura de batchs cuyo nombre informa sobre el contenido:
Elemento |
Builder |
AmqpItemReader |
AmqpItemReaderBuilder |
ClassifierCompositeItemProcessor |
ClassifierCompositeItemProcessorBuilder |
ClassifierCompositeItemWriter |
ClassifiercompositeItemWriterBuilder |
CompositeItemWriter |
CompositeItemWriterBuilder |
FlatFileItemReader |
FlatFileItemReaderBuilder |
FlatFileItemWriter |
FlatFileItemWriterBuilder |
GemfireItemWriter |
GemfireItemWriterBuilder |
HibernateCursorItemReader |
HibernateCursorItemReaderBuilder |
HibernateItemWriter |
HibernateItemWriterBuilder |
HibernatePagingItemReader |
HibernatePagingItemReaderBuilder |
JdbcBatchItemWriter |
JdbcBatchItemWriterBuilder |
JdbcCursorItemReader |
JdbcCursorItemReaderBuilder |
JdbcPagingItemReader |
JdbcPagingItemReaderBuilder |
JmsItemReader |
JmsItemReaderBuilder |
JmsItemWriter |
JmsItemWriterBuilder |
JpaPagingItemReader |
JpaPagingItemReaderBuilder |
MongoItemReader |
MongoItemReaderBuilder |
MultiResourceItemReader |
MultiResourceItemReaderBuilder |
MultiResourceItemWriter |
MultiResourceItemWriterBuilder |
Neo4jItemWriter |
Neo4jItemWriterBuilder |
RepositoryItemReader |
RepositoryItemReaderBuilder |
RepositoryItemWriter |
RepositoryItemWriterBuilder |
ScriptItemProcessor |
ScriptItemProcessorBuilder |
SimpleMailMessageItemWriter |
SimpleMailMessageItemWriterBuilder |
SingleItemPeekableItemReader |
SingleItemPeekableItemReaderBuilder |
StaxEventItemReader... |
Evoluciones de los batchs
No entraremos en detalles, pero el mundo del batch se está moviendo hacia la gestión de procesos externos para poder utilizar las ventajas del cloud, con Spring Batch centrado en el uso de una sola máquina.
Por lo tanto, utilizaremos Spring Cloud Data Flow con Spring Boot Task y Spring Cloud Function.
Spring Cloud Function permite ejecutar funciones bajo demanda a través del equivalente de los lambdas AWS. Spring Boot Task permite gestionar la planificación de tareas y Spring Cloud Data Flow integra la noción de flujo en la ecuación. Esto agrega un nivel de abstracción y es posible planificar un conjunto mucho más grande:
Puntos clave
-
Spring Batch es accesible incluso si tiene poca experiencia en este campo porque los problemas técnicos se gestionan de forma automática.
-
Spring Batch permite convertir fácilmente datos de un formato a otro.
-
En la medida de lo posible, intentaremos procesar los datos en tiempo real para minimizar el número de batchs.