0
0
Lập trình
Admin Team
Admin Teamtechmely

Hướng Dẫn Toàn Diện Về Spring Batch Cho Lập Trình Viên

Đăng vào 1 ngày trước

• 8 phút đọc

Hướng Dẫn Toàn Diện Về Spring Batch Cho Lập Trình Viên

Giới thiệu

Spring Batch là một framework mạnh mẽ trong hệ sinh thái Spring, giúp xây dựng các ứng dụng xử lý batch mạnh mẽ, có khả năng mở rộng và chịu lỗi. Trong phần 5 này, chúng ta sẽ tìm hiểu sâu về các thành phần và cấu hình chính, từ việc cấu hình job cơ bản đến các tính năng tiên tiến như xử lý song song và xử lý lỗi.

Mục Lục

  1. Các Thành Phần Chính và Cấu Hình
  2. Đọc Dữ Liệu Từ Nhiều Nguồn
  3. Quản Lý Trạng Thái và Khả Năng Khởi Động Lại
  4. Kiểm Soát Tệp Đầu Ra
  5. Thực Thi Song Song và Chịu Lỗi
  6. Thực Hành Tốt Nhất
  7. Câu Hỏi Thường Gặp

Các Thành Phần Chính và Cấu Hình

Job Launcher và Task Executor

Để chạy một job trong Spring Batch, bạn cần một JobLauncher. Đối với việc thực thi đồng bộ, bạn có thể sử dụng JobLauncher mặc định. Đối với việc thực thi không đồng bộ, bạn có thể cấu hình TaskExecutorJobLauncher. Điều này rất quan trọng cho các thao tác không chặn, đặc biệt trong các ứng dụng web.

  • @EnableBatchProcessing: Chú thích này cho phép các tính năng của Spring Batch và là cần thiết để chạy một ứng dụng batch dưới dạng máy chủ. Nó tự động cấu hình một JobLauncher mặc định và các thành phần chính khác.
  • TaskExecutorJobLauncher: Triển khai này của JobLauncher chạy các job không đồng bộ bằng cách sử dụng TaskExecutor.
  • SimpleAsyncTaskExecutor: Một TaskExecutor cơ bản sử dụng một luồng mới cho mỗi tác vụ. Bạn có thể kích hoạt các luồng ảo bằng cách thiết lập .setVirtualThread(true) cho các tác vụ nhẹ và có độ đồng thời cao.
java Copy
@Bean
public JobLauncher asyncJobLauncher(JobRepository jobRepository) throws Exception {
    TaskExecutorJobLauncher jobLauncher = new TaskExecutorJobLauncher();
    jobLauncher.setJobRepository(jobRepository);
    SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
    taskExecutor.setVirtualThreads(true);
    jobLauncher.setTaskExecutor(taskExecutor);
    jobLauncher.afterPropertiesSet();
    return jobLauncher;
}

Tasklets

Không phải tất cả các bước trong một job batch đều cần có reader, processor, và writer cổ điển. Đối với các logic quy trình đơn giản như dọn dẹp tệp hoặc lệnh hệ thống, bạn có thể sử dụng một Tasklet.

  • Tasklet: Đây là một giao diện chức năng với một phương thức execute(). Nó trả về một đối tượng RepeatStatus.
  • RepeatStatus:
    • RepeatStatus.CONTINUABLE: Cho framework biết gọi lại phương thức execute(). Điều này hữu ích cho việc lặp lại các tác vụ cho đến khi một điều kiện được đáp ứng.
    • RepeatStatus.FINISHED: Chỉ ra rằng tác vụ đã hoàn thành.

Một Tasklet phải được truyền vào một Step để được thực thi.

java Copy
@Bean
public Step cleanupStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
    return new StepBuilder("cleanupStep", jobRepository)
        .tasklet((contribution, chunkContext) -> {
            // Logic tùy chỉnh của bạn, ví dụ: xóa thư mục tạm thời
            System.out.println("Đang dọn dẹp các tệp tạm thời...");
            return RepeatStatus.FINISHED;
        }, transactionManager)
        .build();
}

Đọc Dữ Liệu Từ Nhiều Nguồn

Xử lý nhiều tệp đầu vào trong một job batch là một yêu cầu phổ biến. Spring Batch cung cấp các thành phần mạnh mẽ cho việc này.

MultiResourceItemReaderBuilder

MultiResourceItemReaderBuilder đơn giản hóa việc đọc từ nhiều tệp. Nó quản lý danh sách các tệp và ủy quyền việc đọc từng tệp cho một ResourceAwareItemReaderItemStream bên dưới.

ResourceAwareItemReaderItemStream

Giao diện này hoạt động như một lớp trung gian. Nó nhận một Resource đơn (ví dụ: một tệp) từ MultiResourceItemReaderBuilder và thiết lập nó trên trình đọc bên trong (như FlatFileItemReader). Nó sau đó quản lý vòng đời của trình đọc này thông qua các phương thức open(), close(), và read(). Nó không tự đọc dữ liệu, chỉ quản lý tài nguyên cho trình đọc thực tế.

FlatFileItemReader

Đây là trình đọc cụ thể đọc các dòng từ một tệp đơn. Nó:

  • Đọc các dòng tuần tự.
  • Giữ lại trạng thái của nó (dòng đã đọc cuối cùng) trong ExecutionContext để có khả năng khởi động lại.
  • Yêu cầu một LineMapper để phân tích mỗi dòng thành một đối tượng.

Quá trình tổng thể như sau:

  1. MultiResourceItemReader nhận một danh sách các tệp (ví dụ: từ inputFolderPath).
  2. Nó ủy quyền một tệp đơn cho MultiFileTeamReader (một triển khai tùy chỉnh của ResourceAwareItemReaderItemStream).
  3. MultiFileTeamReader thiết lập tệp này là tài nguyên cho FlatFileItemReader.
  4. FlatFileItemReader đọc các dòng từ tệp, phân tích chúng thành các đối tượng.
  5. Khi một tệp hoàn tất, MultiResourceItemReader chuyển sang tệp tiếp theo, lặp lại quá trình.

Quản Lý Trạng Thái và Khả Năng Khởi Động Lại

ExecutionContext

ExecutionContext là một kho lưu trữ khóa-giá trị giữ thông tin trạng thái cho một Job hoặc Step. Nó rất quan trọng cho khả năng khởi động lại, vì nó cho phép framework lưu trữ vị trí đã xử lý thành công cuối cùng. Hầu hết các trình đọc và ghi tự động lưu trạng thái của chúng vào ExecutionContext.

ItemStream

Giao diện ItemStream cung cấp một vòng đời cho các thành phần có trạng thái trong Spring Batch.

  • open(ExecutionContext): Được gọi vào đầu một bước để khởi tạo tài nguyên và khôi phục trạng thái.
  • update(ExecutionContext): Được gọi định kỳ để lưu trạng thái hiện tại.
  • close(): Được gọi vào cuối một bước để giải phóng tài nguyên.

FlatFileItemReader triển khai ItemStream để lưu vị trí dòng đã đọc cuối cùng, cho phép một job khởi động lại từ nơi nó đã dừng lại.

Chia Sẻ Dữ Liệu Giữa Các Bước

Để truyền dữ liệu từ bước này sang bước khác, bạn có thể thăng tiến các khóa từ StepExecutionContext lên JobExecutionContext.

  • Thăng Tiến Thủ Công: Truy cập JobExecutionContext qua StepExecution.getJobExecution().getExecutionContext() vào cuối một bước.
  • Thăng Tiến Tự Động: Sử dụng ExecutionContextPromotionListener. Cấu hình nó với các khóa bạn muốn thăng tiến, và nó sẽ tự động chuyển các giá trị đó đến JobExecutionContext.

Bạn có thể truy cập dữ liệu từ JobExecutionContext trong các bước khác bằng cách sử dụng chú thích @Value với biểu thức SpEL #{jobExecutionContext['your.key']}.

java Copy
@Bean
@StepScope
public SomeComponent myComponent(@Value("#{jobExecutionContext['max.score']}") Long maxScore) {
    // ...
}

Kiểm Soát Tệp Đầu Ra

Để thêm tiêu đề hoặc chân trang tùy chỉnh vào một tệp phẳng, bạn có thể sử dụng các callback sau trong FlatFileItemWriter:

  • FlatFileHeaderCallback: Thêm văn bản vào đầu tệp đầu ra.
  • FlatFileFooterCallback: Thêm văn bản vào cuối tệp đầu ra.

Thực Thi Song Song và Chịu Lỗi

Thực Thi Bước Song Song

Bạn có thể chạy nhiều bước song song để cải thiện hiệu suất bằng cách sử dụng SimpleFlow với một TaskExecutor.

  1. Định nghĩa một SimpleFlow riêng cho mỗi bước bạn muốn chạy song song.
  2. Sử dụng một FlowBuilder để tạo một luồng "chia tách", thêm các luồng riêng lẻ vào đó.
  3. Cung cấp một TaskExecutor cho phương thức split() để quản lý các luồng song song.
java Copy
// Định nghĩa một luồng chia tách cho các bước song song
SimpleFlow parallelFlow = new FlowBuilder<SimpleFlow>("parallelFlow")
    .split(new SimpleAsyncTaskExecutor())
    .add(stepOneFlow, stepTwoFlow)
    .build();

// Sử dụng luồng song song trong job của bạn
return new JobBuilder("myParallelJob", jobRepository)
    .start(initialStep)
    .next(parallelFlow) // Thực thi stepOne và stepTwo song song
    .next(finalStep)
    .build();

Khởi Động Lại Jobs

Khả năng khởi động lại jobs là một tính năng cốt lõi của Spring Batch.

  • Jobs Gặp Lỗi: Nếu một job gặp lỗi, bạn có thể khởi động lại nó với cùng tham số. Spring Batch sẽ tự động bỏ qua các bước đã thành công trước đó và chỉ chạy lại các bước đã thất bại.
  • Phiên bản Job Mới: Nếu bạn chạy một job với các tham số mới, nó được coi là một phiên bản mới. Tất cả các bước sẽ chạy từ đầu.
  • allowStartIfComplete(true): Sử dụng cài đặt này trong StepBuilder nếu bạn muốn một bước đã thành công được chạy lại khi một job được khởi động lại. Theo mặc định, các bước thành công sẽ bị bỏ qua. Bạn cần điều này cho các tác vụ phải luôn chạy, như một bước dọn dẹp.
Tình huống Bước có chạy lại không? Cần allowStartIfComplete(true)?
Khởi động lại một job thất bại với cùng tham số Không (trừ khi nó thất bại) , nếu bạn muốn một bước đã hoàn thành chạy lại.
Chạy job với tham số mới Có (đó là một phiên bản job mới) Không.
Khởi động lại một job đã hoàn thành với cùng tham số Không , nếu bạn muốn bất kỳ bước nào chạy lại.

Bỏ Qua và Thử Lại

Cơ chế chịu lỗi của Spring Batch cho phép bạn xử lý các lỗi tạm thời và không quan trọng một cách linh hoạt.

  • Bỏ Qua: Bỏ qua các ngoại lệ cụ thể và tiếp tục xử lý.

    • skip(Exception.class): Bỏ qua các mục gây ra ngoại lệ đã chỉ định.
    • skipLimit(n): Đặt số lượng tối đa các lần bỏ qua được phép trước khi job thất bại.
    • Tốt nhất cho các lỗi không quan trọng, vĩnh viễn (ví dụ: định dạng bản ghi sai).
  • Thử Lại: Thử lại việc xử lý một mục thất bại một số lần nhất định trước khi từ bỏ.

    • retry(Exception.class): Thử lại các mục gây ra ngoại lệ đã chỉ định.
    • retryLimit(n): Đặt số lần thử lại tối đa.
    • Tốt nhất cho các lỗi tạm thời (ví dụ: sự cố mạng tạm thời).

Bạn có thể sử dụng cả hai trong một bước faultTolerant().

Nghe Nhạc

Các listener cung cấp các hook vào vòng đời thực thi job để thực hiện logic tùy chỉnh như ghi log hoặc cảnh báo.

  • SkipListener: Cung cấp các callback (onSkipInRead, onSkipInWrite, onSkipInProcess) để theo dõi các mục đã bị bỏ qua.
  • RetryListener: Cung cấp các callback (open, close, onError) để theo dõi các lần thử lại và kết quả.

Thực Hành Tốt Nhất

  • Tối ưu hóa hiệu suất: Sử dụng các cấu hình như TaskExecutor để tối ưu hóa việc thực thi song song.
  • Quản lý trạng thái: Sử dụng ExecutionContext để duy trì trạng thái giữa các lần thực thi.
  • Thử nghiệm và giám sát: Theo dõi hiệu suất của các job và điều chỉnh các tham số khi cần thiết.

Câu Hỏi Thường Gặp

Spring Batch là gì?

Spring Batch là một framework giúp xử lý dữ liệu theo lô, cho phép bạn thực hiện các tác vụ như đọc, xử lý và ghi dữ liệu.

Có thể khởi động lại một job đã hoàn thành không?

Có, Spring Batch cho phép khởi động lại các job đã hoàn thành, miễn là bạn sử dụng đúng cấu hình.

Làm thế nào để xử lý lỗi trong Spring Batch?

Bạn có thể sử dụng các cơ chế bỏ qua và thử lại để xử lý các lỗi tạm thời và không quan trọng trong quá trình xử lý dữ liệu.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào