为什么这个 Grails 下载行为异常?
Why does this Grails download behave strangely?
我编写了一个连接到 S3 并将文件流式传输回客户端的 Grails 应用程序。到目前为止,这一直很有效,直到我尝试使用它来下载一个大 (2GB) 文件。我看到以下行为:
- 调用controller正常开始下载时,1GB左右后,下载'completes'.
- 打开多个选项卡以触发多个同时下载会导致下载数 MB 后 'complete',尽管每次实际下载量似乎都是随机的。在多台机器上执行同时下载时也可以观察到这种情况。
在这两种情况下,错误消息是相同的:
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
}
我真的很困惑是什么原因造成的。
事实证明,此错误的发生是因为应用 运行 在负载平衡器后面的服务器上,负载平衡器试图缓存通过它的文件。它无法缓存较大的文件,因为它的磁盘有限 space,并且下载失败。
这已通过将应用 运行 的一个本地实例连接到 AWS 并观察到奇怪的行为不再发生来验证。
我编写了一个连接到 S3 并将文件流式传输回客户端的 Grails 应用程序。到目前为止,这一直很有效,直到我尝试使用它来下载一个大 (2GB) 文件。我看到以下行为:
- 调用controller正常开始下载时,1GB左右后,下载'completes'.
- 打开多个选项卡以触发多个同时下载会导致下载数 MB 后 'complete',尽管每次实际下载量似乎都是随机的。在多台机器上执行同时下载时也可以观察到这种情况。
在这两种情况下,错误消息是相同的:
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
}
我真的很困惑是什么原因造成的。
事实证明,此错误的发生是因为应用 运行 在负载平衡器后面的服务器上,负载平衡器试图缓存通过它的文件。它无法缓存较大的文件,因为它的磁盘有限 space,并且下载失败。
这已通过将应用 运行 的一个本地实例连接到 AWS 并观察到奇怪的行为不再发生来验证。