场景:
本地测试正常,发布正式报错,国际会议网站批量下载附件超时
报错日志:
[ERROR] 2019-08-22 09:11:05,232 - (CmsReportServiceImpl.java:174) - 下载错误
org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 2,379,171; received: 993,788)
at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:178) ~[httpcore-4.4.11.jar!/:4.4.11]
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:135) ~[httpclient-4.5.8.jar!/:4.5.8]
at java.util.zip.CheckedInputStream.read(CheckedInputStream.java:82) ~[?:1.8.0_151]
at java.io.FilterInputStream.read(FilterInputStream.java:133) ~[?:1.8.0_151]
…
意思是数据传输被提前终止了,期望传输2,379,171B,只是传输了993,788B
nginx
nginx的参数调过没有作用
oss
1.出错的方式:循环从阿里云上下载完了之后再同一写入本地打包,中间连接会断掉。
for (CmsAttachmentFile attachment : listAttachment) {
if (null == attachment) {
Assert.fail("抱歉!附件不存在");
}
InputStream contractStream = ossClient.download(attachment.getUrl());
mapStream.put(attachment.getName() + "." +attachment.getUrl().split("\\.")[1] , contractStream);
}
try {
OutputStream fos = response.getOutputStream();
List<FileEntry> fileEntryList = Lists.newArrayList();
for (Map.Entry<String, InputStream> streamEntry : mapStream.entrySet()) {
fileEntryList.add(new FileEntry(streamEntry.getValue(), streamEntry.getKey()));
}
2.修改后的方式:循环下载完每一个文件后,写入本地,打包。连续的io操作不会导致超时。
ZipOutputStream zos = null;
int i = 1;
try {
zos = new ZipOutputStream(os);
for (CmsAttachmentFile attachment : listAttachment) {
int readCount;
byte[] bytes = new byte[4096];
zos.putNextEntry(new ZipEntry(attachment.getName() + "(" + i + ")" + "." + attachment.getUrl().split("\\.")[1]));
InputStream is = ossClient.download(attachment.getUrl());
try {
while ((readCount = is.read(bytes)) != -1) {
zos.write(bytes, 0, readCount);
}
} finally {
zos.flush();
IoUtils.close(is);
}
i++;
}
} finally {
IoUtils.close(zos);
}
总结: nginx降低了下载速度让阿里云下载超时