我有一个 sftp 服务器,合作伙伴会向其发送文件。一旦文件到达 sftp 目录,我就想读取其内容并将内容发送到另一台服务器进行进一步处理。
为了实现上述目标,我设置了一个非常精简的文件监视程序,与 sftp 服务器在同一台机器上运行。它使用文件系统事件观察器库订阅 CREATE 事件 - 每当触发此类事件时,观察者就会读取文件并将其内容发送到处理服务器。
这在本地有效。也就是说,如果我mv
从同一台机器将文件发送到 sftp 目录,则内容会被正确解析。但是,当我实际上put
从远程机器将文件发送到 sftp 目录时,会发生以下情况:
- CREATE fs 事件已触发
- SFTP 开始传输数据
- 文件观察器接收 CREATE 事件,打开部分写入的文件,将部分内容发送到远程处理服务器。
- SFTP 完成传输数据。
结果,远程服务器上的内容为空,因为它在传输任何数据之前就读取了文件。我已验证文件最终会收到所有数据。
SFTP put 会触发哪些 FS 事件序列?我应该如何解决上述用例?我正在探索简单的延迟(一旦收到 CREATE 事件,等待 5 秒,然后读取文件),但似乎都无法持续。
答案1
如果依赖inotify
,你应该关注CLOSE_WRITE
事件而不是CREATE
。
如果你不需要递归监控,你可以看看incrond
(和incrontab
)
或者,您可以简单地安排rsync
以短间隔(即:1 分钟)运行并在下班时间清理源目录,此时您可以停止 SFTP 服务(100%确定在清理操作期间没有人上传文件)。
编辑:嗯,看来你选择的图书馆不是提供CLOSE_WRITE
事件,但仅MODIFY
(见这里)。问题MODIFY
是任何写入都会触发单独的事件,这意味着单个大文件上传可以触发不确定数量的MODIFY
事件。
如果您想继续使用通知库,我建议您评估incrond
,lsyncd
或者inotifywait
对于普通rsync
方法,您当然可以结束传输部分上传的文件,但该文件将rsync
在初始上传完成后的下一个周期完全传输。在接收方,您应该确保只处理完全传输的文件(即使使用通知方法,您也应该检查这一点)。
更广泛地说,我强烈建议您使用具有代表性的文件大小样本进行测试,因为使用小文件进行测试可能会隐藏一些影响较大文件的时间相关问题。