0

我们有一个由 4 个 Web 服务器组成的集群,其中包含几个域,其中一个包含很多视频。我们还有一个“登台”服务器,我们通常将文件同步/上传到该服务器,然后从那里通过 bash 脚本将它们全部同步到其他 Web 服务器。

我们遇到的问题是其中相当一部分是手动的。如果在周末,其中一位内容编辑想要替换视频/上传新视频,那么他们需要等到星期一,我们发现他们会将文件上传到其他地方,因为这样更容易等等。

我们需要一个解决方案,以便员工可以将大文件上传到登台服务器,然后将它们同步到其他服务器上。希望没有其他人参与该过程。

一直在看 ajax 文件管理器;通过 sftp 上传使用文件管理器移动文件一些超级同步按钮

4

2 回答 2

0

您为什么不使用某种自动化过程(例如使用 cron)为您执行同步?

您可以让 cron 作业监视“投递箱”目录(或多个目录),然后它可以运行脚本为您执行复制。

或者,您可以让用户提交带有一些元数据的文件,以便在文件上传后更好地路由文件。

简单地说,永远不要让用户“选择”它的去向,而是让他们告诉你“它的用途”,然后让你的脚本“知道”事情的去向以及如何将它们带到那里。

这是一个相当简单的网络应用程序,即使只使用一些 perl CGI 或其他什么。后端管道也很简单。

回复评论...

如果您有一个执行上传到 CGI 的 Web 应用程序,那么在文件完全上传之前,您通常甚至无法“控制”请求。有点取决于您使用的服务器端技术。无论如何,当文件完全上传时,使用网络应用程序很容易“知道”。然后,您的同步过程可以仅依靠元数据来实际对文件进行工作,并且在将文件移动到适当的暂存区域等之前,您不会创建元数据。

如果您只是使用 FTP 或 scp 将文件复制到暂存目录,那么解决方案有两个有两个进程。第一个监视传入目录,第二个实际复制文件。

第一个过程可以简单地如下所示:

cd /your/upload/dir
ls -l > /tmp/newfiles
comm -12 /tmp/lastfiles /tmp/newfiles > /tmp/samefiles
filelist=`awk '{print $9}' /tmp/samefiles`
mv $filelist /your/copy/dir
mv /tmp/newfiles /tmp/lastfiles

这像这样工作:

  • 获取传入上传目录中的当前文件列表。
  • 使用 comm(1) 获取自上次运行进程以来未更改的文件。
  • 使用 awk(1) 获取未更改的文件名。
  • 使用 mv(1) 将文件移动到您的“暂存”目录。
  • 最后,它获取当前文件列表,并使其成为下一次运行的最后一个列表。

这里的魔力是 comm(1)。'comm -12 filea fileb' 为您提供一个文件,其中包含两个文件之间相同的行。如果有新文件进来,那么它的大小会在上传时改变,所以当你在下一分钟运行 'ls -l' 时,它的行将与新行不匹配——大小(最小)会不同. 因此,comm 只会查找日期、文件名和大小未更改的文件。一旦你有了那个列表,剩下的就很简单了。

此过程的唯一假设是您的文件名中没有空格(因此 awk 可以轻松地从列表中获取文件名)。如果您允许空格,您将需要一个更聪明的机制来将“ls -l”行转换为文件名。

此外,'mv $filelist /your/copy/dir' 假定文件名中没有空格,因此也需要对其进行修改(您可以将其滚动到 awk 脚本中,让它进行 system() 调用,也许)。

第二个过程也很简单:

cd /your/copy/dir
for i in *
do
    sync $i
    mv $i /your/file/youve/copied/dir
done

同样,这里的“文件名中没有空格假设”。此过程依赖于您编写的“做正确的事”的同步 shell 脚本。这留给读者作为练习。

同步后,它将文件移动到另一个目录。那里显示的所有文件都已正确“同步”。您也可以简单地删除该文件,但我倾向于不这样做。我可能会将该目录放在“删除一周以上的文件”程序中。这样,如果您遇到问题,您仍然可以在某个地方恢复原始文件。

这东西很简单,但也很健壮。

只要第一个进程的运行速度比上传“慢”(即如果你连续运行两次,你确信文件大小至少会改变),那么运行时间可以是每 1 分钟,每小时,每天,随便。至少,它可以安全地重新启动,并且可以自我恢复。

第二个过程的阴暗面是,如果您的同步过程比您的计划 cron 花费的时间更长。如果您每分钟运行一次,并且运行时间超过一分钟,那么您将有两个进程复制相同的文件。

如果您的同步过程是“安全的”,那么您最终只会复制文件两次……这是一种浪费,但通常是无害的。

您可以通过使用这样的技术来缓解这种情况,以确保您的复制脚本一次不会运行多个。

这就是它的肉。您还可以使用组合(使用网络应用程序上传元数据,并使用通过 cron 自动运行的同步过程)。

您还可以有一个简单的网页,列出 /your/copy/dir 中的所有文件,以便人们可以查看他们的文件是否已同步。如果文件在此目录中,则它尚未完成同步。

于 2009-08-29T00:57:39.427 回答
0

将这些东西放入一个仅用于上传的目录中。然后使用 rsync 将其复制到不同的服务器。不要担心稍后将文件移动到某个地方。Rsync 将使用文件大小 + 修改时间来判断它是否需要将文件从您的保管箱复制到其他服务器。

你的脚本是

#!/bin/bash

servers="monkey cow turtle"

for s in $servers
do
    rsync -r /path/to/dropbox $s:/place/to/putit
done

可以手动启动或通过 cron 运行。你可以让它创建/检查一个 PID 文件,这样只有一个自己会运行,如果你愿意,可以并行同步到服务器等等。如果文件在脚本第一次运行时“中途上传”,它将完成第二次自动。

于 2009-09-04T21:36:17.507 回答