如何可靠地处理外部代理定期上传的文件?
-
05-07-2019 - |
题
这是一种非常常见的情况:某些进程希望每隔30分钟左右在服务器上删除一个文件。简单吧?好吧,我可以想到一些可能出错的方法。
例如,处理文件可能需要花费大约或少于30分钟,因此在完成上一个文件之前,新文件可能会到达。我不希望源系统覆盖我正在处理的文件。
另一方面,文件很大,因此完成上传需要几分钟。我不想开始处理部分文件。这些文件只是通过FTP或sftp传输(我的偏好),因此操作系统级锁定不是一种选择。
最后,我确实需要将文件保留一段时间,以防我需要手动检查其中一个(用于调试)或重新处理一个。
我已经看到很多临时方法来改组上传文件,交换文件名,使用日期戳,触摸“指示符”等。文件以协助同步,等等。我还没有看到的是一个全面的“算法”。用于处理解决并发性,一致性和完整性的文件。
所以,我想在这里挖掘人群的智慧。有没有人看到一种真正的防弹方式来处理批处理数据文件,因此它们从未过早处理,从未在完成之前被覆盖,并且在处理后安全地保存?
解决方案
关键是在发送结束时进行初始杂耍。所有发件人需要做的是:
- 使用唯一的文件名存储文件。
- 文件发送完毕后,将其移至名为eg的子目录中。 <代码>完成代码> 醇>
- 定期扫描
completed
目录中的任何文件。 - 只要文件出现在
completed
中,请将其移至名为eg code的子目录中。processed
,然后从那里开始处理。 - 完成后,可以选择删除它。 醇>
假设只有一个接收者进程,所有接收者需要做的是:
在任何理智的文件系统上,文件移动都是原子的,只要它们出现在同一个文件系统/卷中。所以没有竞争条件。
多个接收器
如果处理的时间可能比传递文件之间的时间长,那么除非您有多个接收方进程,否则您将构建一个待办事项。那么,如何处理多接收器的情况?
简单:每个接收器进程与以前完全一样。关键是我们在处理之前尝试将文件移动到 processed
:那个,同一文件系统文件移动的事实是原子的,意味着即使多个接收器在 completed
中看到相同的文件并尝试移动它,只有一个会成功。您需要做的就是确保检查 rename()
的返回值,或者用于执行移动的任何OS调用,并且只有在成功时才继续处理。如果移动失败,其他一些接收器首先到达那里,所以只需返回并再次扫描 completed
目录。