我有两个服务,第一个是frontend_service和第二个backend_service,我正在从backend_service获取大文件,并尝试使用以下命令通过frontend_service转发给用户 response.getBodyAsStream(),但这会导致frontend_service中出现“ java.lang.OutOfMemoryError:超出了GC开销限制”。
后端服务代码:
`
public static Result downloadLargeFile(String filePath){
File file = new File(filePath);
InputStream inputStream = new FileInputStream(file);
return ok(inputStream);
}
`
frontend_service的代码:
`
public static F.Promise<Result> downloadLargeFile(String filePath) {
//this will call backend_service downloadLargeFile method.
String backEndUrl = getBackEndUrl(filePath);
return getInputStream(backEndUrl);
}
`
`
public static Promise<Result> getInputStream(String url) {
return WS.url(url).get().map(
response -> {
InputStream inputStream = response.getBodyAsStream();
return ok(inputStream);
}
);
}
`
我尝试了建议here的解决方案,方法是一次从inputStream读取几个字节,并在frontend_service中创建tmp文件,并将tmp文件作为frontend_service的输出发送。
`
public static Promise<Result> getInputStream(String url) {
return WS.url(url).get().map(
response -> {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = response.getBodyAsStream();
//write input stream to tmp file
final File tmpFile = new File("/tmp/tmp.txt");
outputStream = new FileOutputStream(tmpFile);
int read = 0;
byte[] buffer = new byte[500];
while((read = inputStream.read(buffer)) != -1){
outputStream.write(buffer, 0 , read);
}
return ok(tmpFile);
} catch (IOException e) {
e.printStackTrace();
return badRequest();
} finally {
if (inputStream != null) {inputStream.close();}
if (outputStream != null) {outputStream.close();}
}
}
);
`
以上代码还引发java.lang.OutOfMemoryError。我正在尝试1 GB的文件。
答案 0 :(得分:0)
我没有“手”的实现,因此我将编写算法。
1。播放使用AsyncHttpClient
下的WS
。您需要获取它,或按照https://www.playframework.com/documentation/2.3.x/JavaWS#Using-WSClient
2。然后,您需要实现AsyncCompletionHandler
,就像在类https://static.javadoc.io/org.asynchttpclient/async-http-client/2.0.0/org/asynchttpclient/AsyncHttpClient.html的描述中一样
3。在onBodyPartReceived
类的AsyncCompletionHandler
方法中,您需要将主体部分推送到分块播放响应。此处描述的虚假响应:https://www.playframework.com/documentation/2.3.x/JavaStream#Chunked-responses
P.S。
关于类似解决方案的讨论,但方向相反-通过“前端”(播放2)服务将流上传到“后端”(亚马逊)服务: https://groups.google.com/d/msg/asynchttpclient/EpNKLSG9ymM/BAGvwl0Wby8J