I posted http://cxf.547215.n5.nabble.com/Disable-multipart-caching-in-temp-files-on-the-server-stream-straight-out-the-socket-td5719255.html这个问题到CXF列表,没有任何运气。那么我们开始吧。我正在尝试将大文件上传到远程服务器(将其视为虚拟机磁盘)。所以我有一个接受上传请求的宁静服务。上传处理程序如下所示:
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Path("/doupload")
public Response receiveStream(MultipartBody multipart) {
List<Attachment> allAttachments = body.getAllAttachments();
Attachment att = null;
for (Attachment b : allAttachments) {
if (UPLOAD_FILE_DESCRIPTOR.equals(b.getContentId())) {
att = b;
}
}
Assert.notNull(att);
DataHandler dh = att.getDataHandler();
if (dh == null) {
throw new WebApplicationException(HTTP_BAD_REQUEST);
}
try {
InputStream is = dh.getInputStream();
byte[] buf = new byte[65536];
int n;
OutputStream os = getOutputStream();
while ((n = is.read(buf)) > 0) {
os.write(buf, 0, n);
}
ResponseBuilder rb = Response.status(HTTP_CREATED);
return rb.build();
} catch (IOException e) {
log.error("Got exception=", e);
throw new WebApplicationException(HTTP_INTERNAL_ERROR);
} catch (NoSuchAlgorithmException e) {
log.error("Got exception=", e);
throw new WebApplicationException(HTTP_INTERNAL_ERROR);
} finally {}
}
这段代码的客户端相当简单:
public void sendLargeFile(String filename) {
WebClient wc = WebClient.create(targetUrl);
InputStream is = new FileInputStream(new File(filename));
Response r = wc.post(new Attachment(Constants.UPLOAD_FILE_DESCRIPTOR,
MediaType.APPLICATION_OCTET_STREAM, is));
}
该代码在功能方面运行良好。在性能方面,我注意到在我的处理程序(receiveStream() 方法)从流中获取第一个字节之前,整个流实际上被保存到临时文件中(使用 CachedOutputStream)。不幸的是,这对于我的目的来说是不可接受的。
- 我的处理程序只是将传入的字节传递到后端存储系统(虚拟机磁盘存储库),等待整个磁盘写入缓存然后再次读取需要花费大量时间,占用大量资源,并且减少吞吐量。
- 由于应用程序在云中运行,并且云提供商按读取/写入的块收费,因此写入块并再次读取它们会产生相关成本。
- 由于每个字节都会写入本地磁盘,因此我的服务 VM 必须有足够的磁盘空间来容纳所有正在上传的流的总大小(即,如果我有 10 个上传,每个上传 100GB,我必须有 1TB 的磁盘来缓存内容)。这又是一笔额外的钱,因为服务虚拟机的大小急剧增长,并且云提供商也会对配置的磁盘大小收费。
鉴于所有这些,我正在寻找一种使用 HTTP InputStream(或尽可能接近它)直接从那里读取附件并随后处理它的方法。我想这个问题可以转化为以下之一:
- 有没有办法告诉CXF不做缓存
- 或者 - 有没有一种方法可以向 CXF 传递一个输出流(我写的一个)来使用,而不是使用 CachedOutputStream
我发现了一个类似的问题here http://mail-archives.apache.org/mod_mbox/cxf-users/200907.mbox/%3C24677330.post@talk.nabble.com%3E。该决议说使用CXF 2.2.3或更高版本,我使用2.4.4(并尝试使用2.7.0)但没有运气。
Thanks.