为什么为 AWS EFS 设置 NFS 同步选项会导致 nginx/Chrome 分块或中断文件上传?

为什么为 AWS EFS 设置 NFS 同步选项会导致 nginx/Chrome 分块或中断文件上传?

问题:为什么使用该选项的 NFS 挂载sync会导致 nginx 和/或 Chrome(以及仅有的Chrome;而不是 Safari、Firefox、Edge 或 curl)来分块或重新启动文件上传?

背景信息:

我在服务器集群前面有 nginx。我们添加了文件上传,并使用 nginx 来处理上传,然后传递通过 X-FILE 头上传文件主体

直到最近,我们才在 nginx 服务器上处理上传,因为集群中的其他应用程序服务器无法访问client_body_temp_path/tmp在本例中)。

我们在 AWS 上运行,因此我配置了一个远程教育(又名 NFS)共享并将其挂载在/mnt/efs,然后将 nginx 更改client_body_temp_path为指向/mnt/efs/tmp

我在所有应用程序服务器上安装了 NFS 共享,现在它们可以访问文件上传/mnt/efs/tmp由于 NFS 异步写入,上传的文件在被其他客户端首次读取时通常为零长度。

我仅在 nginx 服务器上更改了 NFS 挂载,因此它使用以下命令挂载sync

初始挂载:

example.eu-west-1.amazonaws.com:/ /mnt/efs nfs4 vers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,_netdev,nofail

新坐骑:

example.eu-west-1.amazonaws.com:/ /mnt/efs nfs4 vers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,_netdev,nofail,sync

我重新安装了共享并尝试了一些上传和快乐的日子,其他 NFS 客户端看到了非空文件/mnt/efs/tmp

但经过进一步测试,结果发现上传超过 10M 的文件被 Chrome 重启或分块

会发生什么:

nginx 开始接收上传(在下面的视频中,我正在发送一个 32.7MB 的文件),但在 6.4MB 时,新的上传开始,然后最终 nginx 决定客户端停止发送,因此出现问题A499这会导致 Chrome 中止上传,并且一切都会失败。您可以在此处看到所有发生的情况,因为我watch将文件传入/mnt/efs/tmp

http://jay.gooby.org/media/video/chrome%20failing.mp4

上传最初为,0000000006但当达到 6.4M 时,第二次上传0000000007开始(但0000000006继续到 12M),然后当0000000007达到 6.4 时,第三次0000000008上传开始(0000000007继续到 12M)。一旦0000000008达到 12M,ngingx 就会发出499,Chrome 会中止上传。

其他用户代理没有这个问题。我能够使用 Safari、Firefox 和 curl 上传同一个文件。Mac 和 Windows 上的 Chrome 都存在同样的问题。

以下是 curl 发送文件时没有任何问题的情况:它以0000000010单个 32M 文件的形式到达:

http://jay.gooby.org/media/video/curl%20working.mp4

经过一番折腾,我sync从 nginx 服务器上的 NFS 挂载中删除了该选项,结果,使用 Chrome 上传的文件竟然以单个文件的形式完整地到达了。那么到底是怎么回事呢?

nginx 位于弹性 IP 后面,但不位于 ELB 后面,并且上传通过 http2 进行。

nginx 编译时使用--with-threads选项

更新 1: 6.4mb 这个值似乎很重要,因为这是每个新上传块开始/重新开始的点。6.4mb 是 51200000 位,这似乎是一个非常具体的值......

这三个文件的初始字节相同,因此就好像 Chrome 决定从 6.4mb 点开始重新发送:

3 个相同的 mp4 文件头

相关内容