代码之家  ›  专栏  ›  技术社区  ›  Esteban Brenes

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

  •  0
  • Esteban Brenes  · 技术社区  · 16 年前

    情况如下:

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

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

    提供的一个建议是在ftp服务器中运行cronjob,但是有一个服务限制条款,允许cronjob s在共享主机时以30分钟的间隔运行。考虑到上传的工作站数量和上传之间的10分钟间隔,似乎cronjob在两次调用之间的30分钟限制可能是一个问题。

    是否有其他建议的方法?可用的服务器端脚本语言是Perl、PHP和Python。

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

    4 回复  |  直到 16 年前
        1
  •  4
  •   GodEater    16 年前

    大多数现代Linux都支持inotify,让您的进程知道目录的内容何时发生了变化,因此您甚至不需要进行轮询。

    编辑:关于Mark Baker的以下评论:

    “但是要小心,因为文件一创建,就会通知您,而不是在关闭时通知您。因此,您需要某种方法来确保不提取部分文件。”

    这将发生在您在目录级别设置的inotify监视中—确保您随后不会拾取部分文件的方法是在新文件上设置进一步的inotify监视,并查找in-close事件,以便您知道该文件已完全写入。

    一旦您的进程看到了这一点,您就可以删除这个新文件上的inotify表,并在空闲时处理它。

        2
  •  4
  •   bmdhacks    16 年前

    您可以考虑使用一个持续轮询目标目录的持久守护进程:

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

    然后您的cron作业可以尝试每隔30分钟启动一次守护进程。如果守护进程不能抓取锁文件,它就死了,所以不必担心多个守护进程在运行。

    另一个需要考虑的方法是通过HTTPPOST提交文件,然后通过CGI处理它们。这样,您就可以保证在提交时已经妥善处理了这些问题。

        3
  •  1
  •   Mark Baker    16 年前

    30分钟的限制真的很愚蠢。在Linux中启动进程并不是一个昂贵的操作,所以如果您所做的只是检查新文件,那么没有什么好的理由不经常这样做。我们有每分钟运行的cron作业,它们对性能没有任何明显的影响。然而,我意识到这不是你的规则,如果你要坚持主机提供商,你没有选择。

    您需要某种长时间运行的守护进程。简单的方法就是定期进行投票,这可能就是我要做的。inotify是一个更好的选择,它可以让您在创建文件时得到通知。

    您可以使用inotify从Perl到Linux::inotify,或者从python到pyinotify。

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

    通过轮询,您不太可能看到部分文件,但最终会发生这种情况,并且在发生错误时很难重现,所以现在最好处理这个问题。

        4
  •  1
  •   Jay    16 年前

    如果您希望继续使用现有的ftp服务器设置,那么我建议您使用诸如inotify或后台监控进程之类的程序来监视上载目录。如果您对移动到另一个ftp服务器没问题,可以看一下 pyftpdlib 这是一个python ftp服务器库。

    我曾经是Pyftpdlib开发团队的一员,其中一个更常见的请求是在文件上传完成后,提供一种“处理”文件的方法。因此我们创造了一个 on_file_received() 上载完成时触发的回调方法(请参见 issue #79 有关详细信息,请访问我们的问题跟踪程序)。

    如果您对python很熟悉,那么将pyftpdlib作为ftp服务器运行,并从回调方法运行处理代码可能会很好。注意pyftpdlib是异步的,不是多线程的,所以回调方法不能被阻塞。如果需要运行长时间运行的任务,我建议在实际的处理工作中使用单独的Python进程或线程。