如何解决Java挂在FileOutputStream.close()上用于S3-to-EC2下载?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (271)

有一个挂在上面的应用程序FileOutputStream.close()(好吧,真的它挂在本机上,FileOutputStream.close0()但无论如何)。而且......我真的不知道会导致什么。Java / Linux调试专家如何解决这个问题?

我以前常常jstack找到犯罪现场,这里是:

s3-transfer-manager-worker-1" #22 prio=5 os_prio=0 tid=0x00007f9f40007800 nid=0x2e6 runnable [0x00007f9fac4d7000]
   java.lang.Thread.State: RUNNABLE
        at java.io.FileOutputStream.close0(Native Method)
        at java.io.FileOutputStream.access$000(FileOutputStream.java:53)
        at java.io.FileOutputStream$1.close(FileOutputStream.java:356)
        at java.io.FileDescriptor.closeAll(FileDescriptor.java:212)
        - locked <0x00000005c3bbc440> (a java.io.FileDescriptor)
        at java.io.FileOutputStream.close(FileOutputStream.java:354)
        at sun.nio.ch.FileChannelImpl.implCloseChannel(FileChannelImpl.java:139)
        at java.nio.channels.spi.AbstractInterruptibleChannel.close(AbstractInterruptibleChannel.java:115)
        - locked <0x00000005c3bbc600> (a java.lang.Object)
        at com.amazonaws.util.IOUtils.closeQuietly(IOUtils.java:70)
        at com.amazonaws.services.s3.internal.ServiceUtils.appendFile(ServiceUtils.java:473)
        at com.amazonaws.services.s3.transfer.internal.CompleteMultipartDownload.call(CompleteMultipartDownload.java:46)
        at com.amazonaws.services.s3.transfer.internal.CompleteMultipartDownload.call(CompleteMultipartDownload.java:29)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

下载代码

这是我们的S3下载代码的简化版本:

AmazonS3Client s3Client = new AmazonS3Client(new DefaultAWSCredentialsProviderChain());
s3Client.setRegion(...);
TransferManager s3TransferManager = TransferManagerBuilder.standard().withS3Client(s3Client).build();

GetObjectRequest objectRequest = new GetObjectRequest(...);
Path localTempFile = Files.createTempFile(...);
Download downloadHandle = s33TransferManager.download(objectRequest, localTempFile.toFile());

downloadHandle.waitForCompletion();

漂亮的香草。

背景

这是Java AWS S3 API的一种非常普遍的用法,用于将文件下载到本地磁盘。我可以使用aws s3 cp ...命令行应用程序下载相同的文件。更令人困惑的是,该应用程序以前工作得很好。它有大约1000个这样的文件要下载,并且在它开始发生之前它通过了11个文件。

我知道的事情:

  • 这些是健壮的文件,每个大约20 GB。
  • 我已经尝试了多次,让它在那里坐了1:00h,最近在那里,2:00h。它保持挂起。
  • 我们有足够的可用磁盘空间:200 GB。(如果那是问题,它会抛出异常。)
  • 我尝试将其关闭然后再打开(通过sudo reboot)。
  • 这是一个m4.2xlargeEC2实例。
  • 根据CloudWatch,CPU不忙。
  • 我可以通过aws s3 cp ...命令行从S3下载完全相同的文件到完全相同的位置,排除了:
    • 磁盘空间问题(再次)。
    • IOPS短缺(除非Java SDK TransferManager正在做一些非常不同和愚蠢的事情)。
    • 下载速度非常慢:在命令行上下载文件只需要大约5分钟。
    • 文件权限问题。

提问于
用户回答回答于

我几乎不愿意这样说,因为它是每个编码员最喜欢的跟踪马,但“它是商业安全软件。” 当我们禁用扫描过程时,它会神奇地修复自己。

事实证明,它并没有完全悬挂,它只是.part非常缓慢地组装所有下载的文件:每40秒一个8MB的块。我猜安全过程是拦截文件写入并以某种方式纠缠它们?我不知道'。

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励