为什么这个Grails下载行为奇怪?

时间:2015-01-09 10:43:21

标签: grails groovy amazon-s3

我编写了一个连接到S3的Grails应用程序,并将文件流回客户端。到目前为止,这已经很好用了,直到我试图用它来下载一个大的(2GB)文件。我看到以下行为:

  • 通过调用控制器正常开始下载时,大约1GB后,下载“完成”。
  • 打开多个标签以触发多个同时下载会导致下载在几MB之后“完成”,尽管每次下载的实际数量似乎是随机的。在多台计算机上同时下载时也可以观察到这种情况。

在这两种情况下,错误消息都是相同的:

errors.GrailsExceptionResolver SocketException occurred when processing request: [GET] /download
Connection reset.:
java.net.SocketException: Connection reset

errors.GrailsExceptionResolver IllegalStateException occurred when processing request: [GET] /download
getOutputStream() has already been called for this response.

以下是与下载相关的控制器部分:

DownloadController.groovy

def index() {
    def fileStream = s3Service.getStream()
    response.setHeader("Content-disposition", "attachment;filename=foo.csv")
    response.contentType = "text/csv"
    response.outputStream = fileStream
    response.outputStream.flush()
}

..以及连接到S3并获取文件的服务片段:

S3Service.groovy

def getStream() {
    def outputStream = ""
    try {
        AmazonS3 s3 = new AmazonS3Client()
        S3Object object = s3.getObject(new GetObjectRequest('my-bucket-name', 'path/to/file.csv'))
        outputStream = object.getObjectContent()
    }
    catch (AmazonServiceException ase) {
        /* Log the error. Omitted for brevity. */
    }
    catch (AmazonClientException ase) {
        /* Log the error. Omitted for brevity. */
    }
    return outputStream
}

我真的很难过导致这种情况的原因。

1 个答案:

答案 0 :(得分:2)

事实证明发生此错误是因为应用程序正在负载均衡器后面的服务器上运行,负载均衡器正在尝试缓存通过它的文件。由于磁盘空间有限,它无法缓存较大的文件,下载失败。

通过将本地运行的应用程序实例连接到AWS,并观察到不再出现这种奇怪行为来验证这一点。

相关问题