首页 > 解决方案 > Spring Batch 读取 XML 的最佳架构

问题描述

在 Spring Batch 中读取 XML 的最佳性能架构是什么?每个 XML 大小约为 300 KB,我们正在处理 100 万个。

我们目前的方法

  1. 30 个分区和 30 个网格,每个从站获得 166 个 XMLS

  2. 提交块 100

  3. 应用程序启动内存为 8 GB

  4. 在阅读器默认 Bean 范围中使用 JAXB

@StepScope
@Qualifier("xmlItemReader")
public IteratorItemReader<BaseDTO> xmlItemReader(
        @Value("#{stepExecutionContext['fileName']}") List<String> fileNameList) throws Exception {
    String readingFile = "File Not Found";
    logger.info("----StaxEventItemReader----fileName--->" + fileNameList.toString());
    List<BaseDTO> fileList = new ArrayList<BaseDTO>();
    for (String filePath : fileNameList) {
        try {
            readingFile = filePath.trim();
            Invoice bill = (Invoice) getUnMarshaller().unmarshal(new File(filePath));
            UnifiedInvoiceDTO unifiedDTO = new UnifiedInvoiceDTO(bill, environment);
            unifiedDTO.setFileName(filePath);
            BaseDTO baseDTO = new BaseDTO();
            baseDTO.setUnifiedDTO(unifiedDTO);
            fileList.add(baseDTO);
        } catch (Exception e) {
            UnifiedInvoiceDTO unifiedDTO = new UnifiedInvoiceDTO();
            unifiedDTO.setFileName(readingFile);
            unifiedDTO.setErrorMessage(e);
            BaseDTO baseDTO = new BaseDTO();
            baseDTO.setUnifiedDTO(unifiedDTO);
            fileList.add(baseDTO);
        }
    }
    return new IteratorItemReader<>(fileList);
}

我们的问题:

  1. 这个架构是否正确
  2. 与 JAXB 相比,使用 StaxEventItemReader 和 XStreamMarshaller 是否具有任何性能或架构优势。
  3. 如何正确处理内存以避免变慢

标签: springspring-bootjaxbspring-batch

解决方案


我将通过使用文件名作为作业参数为每个 xml 文件创建一个作业。这种方法有很多好处:

  • 可重新启动性:如果作业失败,您只需重新启动失败的文件(从它停止的地方开始)
  • 可扩展性:这种方法允许您并行运行多个作业。如果单台机器不够用,可以将负载分散到多台机器上
  • 日志记录:日志在设计上是分开的,您不需要使用 MDC 或任何其他技术来分隔日志

我们在 *.txt 文件中接收 XML 文件路径

您可以创建一个迭代这些行的脚本并每行(也就是每个文件)启动一个作业。Gnu Parallel(或类似工具)是并行启动作业的好选择。


推荐阅读