English 中文(简体)
如何可靠地处理定期由外部代理上传的文件?
原标题:
  • 时间:2009-03-07 20:06:29
  •  标签:

这是一个非常常见的情景:一些进程想每隔30分钟在服务器上放置一个文件。 很简单,对吧? 嗯,我可以想到很多这可能会出错的方式。

例如,处理一个文件可能需要超过或少于30分钟,因此在我完成前一个文件之前,新文件可能会到达。我不希望源系统覆盖我仍在处理的文件。

另一方面,这些文件很大,因此需要几分钟才能完成上传。我不想开始处理部分文件。这些文件只是通过FTP或sftp(我个人偏好)传输,因此不能使用操作系统级别的锁定。

最后,我确实需要保存这些文件一段时间,以防需要手动检查其中的文件(用于调试)或重新处理其中的一个文件。

我看到了许多临时方法来处理上传文件的洗牌,交换文件名,使用日期戳,触摸“指示器”文件以帮助同步等等。但我还没有看到一个全面的“算法”来处理文件,解决并发、一致性和完整性问题。

所以,我想要借助众人的智慧。有人看到过一种真正强大的方法来处理批量数据文件,使其永远不会被提前处理,在处理完成前永远不会被覆盖,并且在处理完成后得到安全保存吗?

最佳回答

关键是在“发送”端进行初始切换。发送方所需要做的就是:

  1. Store the file with a unique filename.
  2. As soon as the file has been sent, move it to a subdirectory called e.g. completed.

假设只有一个接收进程,接收器只需要做的是:

  1. Periodically scan the completed directory for any files.
  2. As soon as a file appears in completed, move it to a subdirectory called e.g. processed, and start working on it from there.
  3. Optionally delete it when finished.

在任何正常的文件系统中,只要文件移动在同一个文件系统/卷内发生,它们就是原子的。因此没有竞争条件。

Multiple Receivers

如果处理时间可能长于文件交付之间的时间段,除非您有多个接收器进程,否则您将会积压。那么,如何处理多接收器的情况?

简单:每个接收器进程的操作与以前完全相同。 关键是我们尝试在处理之前将文件移动到已处理​​,并且同一文件系统的文件移动是原子的,这意味着即使多个接收器在完成目录中看到相同的文件并尝试移动它,只有一个会成功。 您所需要做的就是确保检查rename()的返回值,或使用执行移动的任何操作系统调用,并且仅在成功后继续进行处理。 如果移动失败,则其他接收器首先到达,因此只需返回并再次扫描已完成目录即可。

问题回答

如果操作系统支持,使用文件系统钩子来拦截打开和关闭文件操作。类似于Dazuko。其他操作系统可能会以另一种方式告知您文件操作,例如Novell Open Enterprise Server允许您定义时期,以及读取在时期期间修改的文件列表。

刚刚意识到在Linux中,您可以使用inotify子系统或inotify-tools软件包中的工具。

文件传输是系统集成中的经典之一。我建议你阅读《企业集成模式》这本书,以建立自己对这些问题的答案——在某种程度上,答案取决于你用于端点实现和文件传输的技术和平台。这是一个相当全面的可行模式集合,写得相当不错。





相关问题
热门标签