Amazon s3 将文件从S3直接流式传输到响应

Amazon s3 将文件从S3直接流式传输到响应,amazon-s3,jersey,dropwizard,Amazon S3,Jersey,Dropwizard,我有以下代码作为S3 bucket的网关。其目的是下载位于S3上的文件,但不公开S3项链接。 所有这些都可以正常工作,但在大约50次下载之后,我们一直在等待来自池的连接超时。 我发现这可能是由于没有关闭s3Object.getObjectContent()导致的,但正如您所看到的,我使用的是“try with resources”,它确保调用close()。我不仅在流上这样做,而且在对象本身上也这样做。这是最后的手段,因为它不会改变任何事情。事实上,S3Object.close()做了同样的事情

我有以下代码作为S3 bucket的网关。其目的是下载位于S3上的文件,但不公开S3项链接。 所有这些都可以正常工作,但在大约50次下载之后,我们一直在等待来自池的连接超时。 我发现这可能是由于没有关闭
s3Object.getObjectContent()
导致的,但正如您所看到的,我使用的是“try with resources”,它确保调用
close()
。我不仅在流上这样做,而且在对象本身上也这样做。这是最后的手段,因为它不会改变任何事情。事实上,S3Object.close()做了同样的事情——关闭底层的InputStream

手动测试时,可以看到正在调用
close()

@GET
@Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON})
@Path("/{id}/download")

public Response download(@NotNull @PathParam("id") String id) {
    return repository.get()
        .map(record -> Response.status(OK)
            .header(HttpHeaders.CONTENT_DISPOSITION, "...")
            .entity((StreamingOutput) outputStream -> {
                try (S3Object s3Object = s3Service.getObject(record.getS3Key());
                    InputStream inputStream = s3Object.getObjectContent()) {

                    byte[] buffer = new byte[1024];
                    int bytesRead;
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                        outputStream.flush();
                    }
                    outputStream.flush();
                }
            })
            .build())
        .orElseThrow(() -> new EntityNotFoundException(String.format("Could not find download id: %s", id)));
}
[编辑]

  • AWS S3 java库版本1.11.308
  • AmazonS3被设置为一个单亲家庭

似乎您必须在关闭流之前调用流
is.skip(Long.MAX_VALUE)

try (InputStream is =new DrainOnCloseInputStream(s3Object.getObjectContent())) {
            processFile(is,fileExt, context, logGroupName, logStreamName);
}

public class DrainOnCloseInputStream extends FilterInputStream {
    public DrainOnCloseInputStream(InputStream paramInputStream) {
        super(paramInputStream);
    }

    @Override
    public void close() throws IOException {
        drain(in);
        super.close();
    }

    private static void drain(InputStream is) throws IOException {
        is.skip(Long.MAX_VALUE);
    }
}

答案对你有帮助吗,还是有不同的解决方案?我也有类似的问题。