我的文件处理方案是,
read input file -> process -> generated output file
但我必须有两台物理上不同的机器,它们连接到一个存储区域,我接收所有输入文件和一台数据库服务器,这些机器上运行着两台应用程序服务器(每台服务器上一台)。
那么如何使用spring批处理并行处理这两个应用程序服务器上的输入文件呢?我的意思是如果服务器1(P1)上有5个文件和(P2)上有5个文件有10个文件,可以完成吗?
我的文件处理方案是,
read input file -> process -> generated output file
但我必须有两台物理上不同的机器,它们连接到一个存储区域,我接收所有输入文件和一台数据库服务器,这些机器上运行着两台应用程序服务器(每台服务器上一台)。
那么如何使用spring批处理并行处理这两个应用程序服务器上的输入文件呢?我的意思是如果服务器1(P1)上有5个文件和(P2)上有5个文件有10个文件,可以完成吗?
您可以为每个输入文件安排一个作业(输入文件位置将是作业的参数)。Spring Batch 将保证不会创建具有相同作业参数的两个作业实例。如果另一个节点已经开始处理相同的文件,您将得到一个JobExecutionAlreadyRunningException
或。JobInstanceAlreadyCompleteException
首先要决定您是否真的要将文件分成两半(5 和 5),或者您是否希望每个服务器都处理直到完成?如果文件大小不一,有的小,有的大,您最终可能会得到最佳并行化,在一台服务器上处理 6 个,在另一台服务器上处理 4 个,或者 7 个和 3 个,如果 3 个由于差异而花费的时间与其他 7 个一样长在尺寸方面。
一个非常基本的方法是拥有一个可以表示活动处理的数据库表。您的作业可以读取目录,获取第一个文件名,然后将其插入到该 JVM 正在处理的表中。如果表的主键是文件名,那么如果它们同时尝试,一个会失败,一个会成功。成功在表中插入条目的人获胜并开始处理文件。另一个必须处理该异常,选择下一个文件,并尝试将其作为处理条目插入。这样,每个人基本上都建立了一个集中锁(在 db 表中),并且您可以获得更有效的处理,该处理考虑文件大小而不是文件分布。
以下是我的建议:
在 db 中创建一个锁定表,文件路径作为主键。然后尝试使用此键插入记录 - 如果成功,您的代码可以继续并处理文件,如果失败(例外,具有此主键的记录存在),然后转到下一个文件。
精确的调度,正如 Jimmy 前面提到的
您可以尝试使用队列(如 ActiveMQ、RabittMQ、...)来同步您的机器
有一种非常简单的方法。如果我理解正确,您将每个文件放入数据库中(有关它的一些信息),然后删除以创建新输出。你可以 Lock() 就可以了,在阅读文件之前你检查
for(File file : fileList.getFiles())
try{
(getting file + process it)
}
并在进行中
file.lock();
try {
...
} finally {
file.unlock();
}
这是有关Lock的一些信息。