这是一种非常常见的情况:某些进程希望每隔30分钟左右在服务器上删除一个文件。简单吧?好吧,我可以想到一些可能出错的方法。
例如,处理文件可能需要花费大约或少于30分钟,因此在完成上一个文件之前,新文件可能会到达。我不希望源系统覆盖我正在处理的文件。
另一方面,文件很大,因此完成上传需要几分钟。我不想开始处理部分文件。这些文件只是通过FTP或sftp传输(我的偏好),因此操作系统级锁定不是一种选择。
最后,我确实需要将文件保留一段时间,以防我需要手动检查其中一个(用于调试)或重新处理一个。
我已经看到了许多改组上传文件的临时方法,交换文件名,使用日期戳,触摸“指标”文件以协助同步等等。我还没有看到的是一个全面的“算法”,用于处理解决并发性,一致性和完整性的文件。
所以,我想在这里挖掘人群的智慧。有没有人看到一种真正的防弹方式来处理批处理数据文件,因此它们从未过早处理,从未在完成之前被覆盖,并且在处理后安全地保存?
答案 0 :(得分:1)
关键是在发送结束时进行初始杂耍。所有发件人需要做的是:
completed
。假设只有一个接收者进程,所有接收者需要做的是:
completed
目录中的任何文件。completed
中,请将其移至名为“{1}}”的子目录中。 processed
,并从那里开始研究。在任何理智的文件系统上,文件移动都是原子的,只要它们出现在同一个文件系统/卷中。所以没有竞争条件。
如果处理时间可能比传递文件之间的时间长,那么除非您有多个接收方进程,否则您将构建一个待办事项。那么,如何处理多接收器的情况?
简单:每个接收器进程与以前完全一样。关键是我们在处理文件之前尝试将文件移动到processed
:那个,同一文件系统文件移动的事实是原子的,这意味着即使多个接收者看到completed
中的同一文件并尝试移动它,只有一个会成功。您需要做的就是确保检查rename()
的返回值,或者您用于执行移动的任何OS调用,并且只有在成功时才继续处理。如果移动失败,其他一些接收器首先到达那里,所以只需返回并再次扫描completed
目录。
答案 1 :(得分:1)
如果操作系统支持,请使用文件系统挂钩拦截打开和关闭文件操作。像Dazuko这样的东西。其他操作系统可能会以一种方式让您了解文件操作,例如,Novell Open Enterprise Server允许您定义纪元,以及read在纪元期间修改的文件列表。
刚才意识到在Linux中,你可以使用inotify子系统,或者来自inotify-tools包的实用程序
答案 2 :(得分:0)
文件传输是系统集成的经典之一。我建议你让Enterprise Integration Patterns书来建立你自己对这些问题的答案 - 在某种程度上,答案取决于你用于端点实现和文件传输的技术和平台。这是一个相当全面的可行模式集合,写得很好。