Przetwarzanie wsadowe raportów Excel w Spring Batch: architektura i implementacja
Spring Batch rozwiązuje problem synchronicznego generowania setek dokumentów Excel w jednym żądaniu HTTP. Framework dzieli proces na porcje, zarządza stanem i zapewnia odzyskiwanie po awariach. W rzeczywistym projekcie automatyzacji napraw silników lotniczych umożliwiło to użytkownikom uruchamianie drukowania wsadowego kart roboczych i list przewozowych bez przekroczeń czasu.
Główne komponenty Spring Batch
Job łączy cały cykl: generowanie Excel, archiwizację, przesyłanie do magazynu i czyszczenie. Step — etap przetwarzania, Tasklet — operacja atomowa.
Proces dzieli się na kroki chunk-oriented (odczyt/przetwarzanie/zapis porcjami) i tasklet-based (jedno działanie). Zapewnia to niezależność etapów i scentralizowane zarządzanie.
Kroki generowania raportów
Krok PRINT: tworzenie plików Excel
Dane są dzielone na porcje po 10 elementów. Każda przechodzi przez reader → processor → writer:
@Bean
@JobScope
public Step printTrpTagsStep(
ItemReader<TrpTagForPrintModel> excelTrpTagItemReader,
ItemProcessor<TrpTagForPrintModel, ExcelItem> excelTrpTagItemProcessor,
ItemWriter<ExcelItem> excelTrpTagItemWriter
) {
return new StepBuilder(BatchExcelPrintStep.PRINT.getCode(), jobRepository)
.<TrpTagForPrintModel, ExcelItem>chunk(10)
.transactionManager(transactionManager)
.reader(excelTrpTagItemReader)
.processor(excelTrpTagItemProcessor)
.writer(excelTrpTagItemWriter)
.build();
}
Spring Batch śledzi writeCount dla postępu. Pliki są zapisywane w /tmp/engine/{timestamp}/zip/ z podkatalogami według typów dokumentów.
Krok ZIP: pakowanie archiwum
Tasklet skanuje katalog i tworzy ZIP standardowymi narzędziami Java.
Krok UPLOAD: umieszczenie w S3
Archiwum jest przesyłane do S3, a link jest zapisywany w ExecutionContext.
Krok CLEAN_UP: usuwanie danych tymczasowych
JobExecutionListener sprawdza status i czyści /tmp w przypadku sukcesu lub awarii.
Równoległość i skalowanie
Kilka Job jest uruchamianych w Thread Pool do jednoczesnego przetwarzania żądań użytkowników. Wewnątrz Job nie stosowano kroków równoległych, ale framework je obsługuje.
Integracja z frontendem: monitorowanie postępu
POST /trp-tag/print/excel/batch/start zwraca jobExecutionId. GET /trp-tag/print/excel/batch/{id} dostarcza status.
Postęp jest obliczany w następujący sposób:
- PRINT: proporcjonalnie do writeCount (90% czasu).
- Pozostałe kroki: 0% lub 100%.
Frontend otrzymuje:
- progressPercentage dla paska.
- currentStepNumber/totalStepsNumber.
- status (STARTED/COMPLETED/FAILED).
- downloadUrl.
- failureDetails.
- durationMillis.
Zalety wdrożenia
- Asynchroniczność: natychmiastowa odpowiedź zamiast przekroczeń czasu.
- Trwałość: historia w PostgreSQL bez dodatkowej infrastruktury.
- Transakcyjność: automatyczne zarządzanie stanem, w przeciwieństwie do @Async.
Co jest ważne
- Chunk po 10 elementów minimalizuje pamięć i zapewnia postęp.
- WriteCount — wbudowany licznik do precyzyjnego śledzenia.
- ExecutionContext przechowuje linki do artefaktów.
- JobExecutionListener gwarantuje czyszczenie.
- Thread Pool skaluje kilka Job jednocześnie.
Spring Batch nadaje się do każdego wsadowego generowania dokumentów z archiwizacją i przechowywaniem. Implementacja zajmuje mniej czasu niż niestandardowa logika z kolejkami.
— Editorial Team
Brak komentarzy.