处理文本文件ftp到托管服务器中的一组目录中

时间:2008-10-16 14:25:20

标签: linux ftp shared-hosting cron

情况如下:

一系列远程工作站收集现场数据,并通过ftp将收集的现场数据ftp到服务器。数据作为CSV文件发送,存储在FTP服务器中每个工作站的唯一目录中。

每个工作站每10分钟发送一次新更新,导致以前的数据被覆盖。我们想以某种方式自动连接或存储这些数据。工作站的处理是有限的,不能扩展,因为它是一个嵌入式系统。

提出的一个建议是在FTP服务器中运行cronjob,但是服务条款限制只允许cronjobs以30分钟的间隔进行,因为它是共享托管。鉴于上传的工作站数量和上传之间的10分钟间隔,看起来cronjob的30分钟限制可能是一个问题。

是否有其他可能建议的方法?可用的服务器端脚本语言是perl,php和python。

升级到专用服务器可能是必要的,但我仍然希望得到如何以最优雅的方式解决此问题的输入。

4 个答案:

答案 0 :(得分:4)

您可能会考虑一个持久守护进程来持续轮询目标目录:

grab_lockfile() or exit();
while (1) {
    if (new_files()) {
        process_new_files();
    }
    sleep(60);
}

然后你的cron作业可以尝试每30分钟启动一次守护进程。如果守护进程无法获取锁定文件,它就会死掉,所以不用担心多个守护进程在运行。

另一种考虑的方法是通过HTTP POST提交文件,然后通过CGI处理它们。这样,您就可以保证在提交时已经妥善处理了这些内容。

答案 1 :(得分:4)

大多数现代Linux都支持inotify,让你的进程知道一个指针的内容何时发生了变化,所以你甚至不需要轮询。

编辑:关于Mark Ba​​ker的以下评论:

“但要小心,因为一旦创建文件就会收到通知,而不是在文件关闭时通知你。所以你需要一些方法来确保你不会收集部分文件。”

使用您在目录级别设置的inotify监视会发生这种情况 - 确保您不接收部分文件的方法是在新文件上设置进一步的inotify监视并查找IN_CLOSE事件,以便你知道该文件已被完全写入。

一旦您的流程看到此消息,您就可以删除此新文件上的inotify手表,并随意处理。

答案 2 :(得分:1)

30分钟的限制确实非常愚蠢。在linux中启动进程并不是一项昂贵的操作,所以如果您所做的只是检查新文件,那么没有理由不经常这样做。我们有每分钟运行的cron作业,它们对性能没有任何明显的影响。但是,我意识到这不是你的规则,如果你要坚持使用那个托管服务提供商,你就没有选择。

你需要一个长跑的守护进程。简单的方法就是定期轮询,这可能就是我要做的事情。 Inotify,因此您可以在创建文件后立即收到通知,这是一个更好的选择。

您可以在Linux :: Inotify中使用perl的inotify,或者使用pyinotify从python使用inotify。

但请注意,因为您会在创建文件后立即通知您,而不是在文件关闭时通知您。所以你需要一些方法来确保你不要拿起部分文件。

通过轮询,你不太可能看到部分文件,但它最终会发生,并且当它确实发生时将是一个令人讨厌的难以重现的错误,所以现在更好地处理问题。

答案 3 :(得分:1)

如果您希望继续使用现有的FTP服务器设置,那么我建议您使用inotify或daemonized进程等内容来观看上传目录。如果您可以移动到其他FTP服务器,可以查看pyftpdlib这是一个Python FTP服务器库。

我一直是pyftpdlib开发团队的一员,而且一个更常见的请求就是在文件上传完成后“处理”文件。因此,我们创建了一个on_file_received()回调方法,该方法在完成上传时触发(有关详细信息,请参阅我们的问题跟踪器上的issue #79)。

如果您对Python感到满意,那么将pyftpdlib作为您的FTP服务器运行并从回调方法运行处理代码可能会很好。请注意,pyftpdlib是异步的而不是多线程的,因此您的回调方法无法阻止。如果您需要运行长时间运行的任务,我建议使用单独的Python进程或线程来进行实际的处理工作。