У нас есть сервер Weblogic, работающий в Linux с несколькими управляемыми серверами. Максимальный размер кучи управляемого сервера, которым я занимаюсь, составляет 1024 МБ. На этом сервере развернуто несколько приложений. Одно из этих приложений обрабатывает ответ от API REST для загрузки файлов размером до 250 МБ. Для файлов размером более 50 МБ иногда не возникает проблем, но иногда происходит сбой сервера с ошибкой OOM. Вот мой код:
Client client = Client.create();
WebResource webResource = client.resource(url.toString());
ClientResponse response = webResource.accept("application/json").get(ClientResponse.class);
if (response.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : "+ response.getStatus());
}
String output = response.getEntity(String.class);
byte[] fileContent = Base64.decodeBase64(output.getBytes());
if (fileContent != null) {
OutputStream out = null;
try {
res.reset();
out = res.getOutputStream();
res.setContentType(contentType);
res.setHeader("Content-Disposition", "inline; filename=" + fileName + "; size=" + String.valueOf(fileContent.length));
res.setContentLength(fileContent.length);
out.write(fileContent);
} catch (Exception ex) {
e.printStackTrace();
} finally {
out.flush();
out.close();
}
}
Поскольку были проблемы с памятью, я попытался использовать подход InputStream. Ниже приведен измененный код:
Client client = Client.create();
WebResource webResource = client.resource(url.toString());
ClientResponse response = webResource.accept("application/json").get(ClientResponse.class);
if (response.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : "+ response.getStatus());
}
InputStream source = response.getEntityInputStream(); // IS THIS OKAY?
if (source!= null) {
OutputStream out = null;
int count = 0;
try {
byte[] buffer = new byte[1024];
int read = 0;
res.reset();
res.setContentType(contentType);
res.setHeader("Content-Disposition", "inline; filename=" + fileName);
out = res.getOutputStream();
while ((read = source.read(buffer)) != -1) {
out.write(buffer, 0, read);
count++;
}
System.out.println("COUNT: " + count);// For a 60MB file, this prints 86000. why?
} catch (Exception ex) {
e.printStackTrace();
}finally{
out.flush();
out.close();
source.close();
}
Этот код не работает в OOM, но файл не загружается / поврежден. Связана ли проблема с тем, что это ответ в кодировке Base64, и я не обрабатываю его должным образом? Если да, что мне делать? Приложение работает на Java 7. Мой подход использует InputStream для решения OOM, хорошо? Служба не отправляет ответ кусками. Какие еще пути я мог бы пойти дальше? Я беспокоюсь, что я сталкиваюсь с ошибками (не всегда) только для 50 МБ файла. Сервер является удаленным и обрабатывается другой группой. Как я могу проверить, есть ли другие причины, ответственные за сбои сервера?