Spring Batch 最值得阅读的架构 XML
Spring Batch Best Architecture to Read XML
在 Spring 批处理中读取 XML 的最佳性能架构是什么?每个 XML 大约有 300 KB 大小,我们正在处理 100 万个。
我们目前的方法
30 个分区和 30 个网格,每个从机获得 166 XMLS
提交块 100
应用程序启动内存为 8 GB
在 Reader 默认 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);
}
我们的问题:
- 这个架构是否正确
- 与 JAXB 相比,使用 StaxEventItemReader 和 XStreamMarshaller 是否有任何性能或架构优势。
- 如何正确处理内存以避免变慢
我将通过使用文件名作为作业参数为每个 xml 文件创建一个作业。这种方法有很多好处:
- 可重启性:如果作业失败,您只能重启失败的文件(从它停止的地方)
- 可扩展性:这种方法允许您 运行 并行执行多个作业。如果单台机器不够用,可以把负载分散到多台机器上
- 日志记录:日志在设计上是分离的,您不需要使用 MDC 或任何其他技术来分离日志
We are receiving XML filepath in a *.txt file
您可以创建一个脚本来遍历这些行并每行(也就是每个文件)启动一个作业。 Gnu Parallel(或类似工具)是并行启动作业的不错选择。
在 Spring 批处理中读取 XML 的最佳性能架构是什么?每个 XML 大约有 300 KB 大小,我们正在处理 100 万个。
我们目前的方法
30 个分区和 30 个网格,每个从机获得 166 XMLS
提交块 100
应用程序启动内存为 8 GB
在 Reader 默认 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);
}
我们的问题:
- 这个架构是否正确
- 与 JAXB 相比,使用 StaxEventItemReader 和 XStreamMarshaller 是否有任何性能或架构优势。
- 如何正确处理内存以避免变慢
我将通过使用文件名作为作业参数为每个 xml 文件创建一个作业。这种方法有很多好处:
- 可重启性:如果作业失败,您只能重启失败的文件(从它停止的地方)
- 可扩展性:这种方法允许您 运行 并行执行多个作业。如果单台机器不够用,可以把负载分散到多台机器上
- 日志记录:日志在设计上是分离的,您不需要使用 MDC 或任何其他技术来分离日志
We are receiving XML filepath in a *.txt file
您可以创建一个脚本来遍历这些行并每行(也就是每个文件)启动一个作业。 Gnu Parallel(或类似工具)是并行启动作业的不错选择。