0
我正在爲一個LMS功能工作,以便即時下載一堆選定的文件和文件夾。我使用ZipOutputStream來防止OutOfMemory問題。ZipOutputStream的併發使用使用100%的CPU
該功能很好,但我們做了壓力測試,當幾個用戶同時下載zip文件(可以說10個用戶每個壓縮大約100MB),4個CPU中有4個達到100%的負載直到拉鍊被創建。我們的系統管理員認爲這是不可接受的。
我不知道是否有一些機制可以做ZipOutputStream使用較少的系統資源,無論是否需要更多時間才能完成。
我當前的代碼:
protected void compressResource(ZipOutputStream zipOut, String collectionId, String rootFolderName, String resourceId) throws Exception
{
if (ContentHostingService.isCollection(resourceId))
{
try
{
ContentCollection collection = ContentHostingService.getCollection(resourceId);
List<String> children = collection.getMembers();
if(children != null)
{
for(int i = children.size() - 1; i >= 0; i--)
{
String child = children.get(i);
compressResource(zipOut,collectionId,rootFolderName,child);
}
}
}
catch (PermissionException e)
{
//Ignore
}
}
else
{
try
{
ContentResource resource = ContentHostingService.getResource(resourceId);
String displayName = isolateName(resource.getId());
displayName = escapeInvalidCharsEntry(displayName);
InputStream content = resource.streamContent();
byte data[] = new byte[1024 * 10];
BufferedInputStream bContent = null;
try
{
bContent = new BufferedInputStream(content, data.length);
String entryName = (resource.getContainingCollection().getId() + displayName);
entryName=entryName.replace(collectionId,rootFolderName+"/");
entryName = escapeInvalidCharsEntry(entryName);
ZipEntry resourceEntry = new ZipEntry(entryName);
zipOut.putNextEntry(resourceEntry); //A duplicate entry throw ZipException here.
int bCount = -1;
while ((bCount = bContent.read(data, 0, data.length)) != -1)
{
zipOut.write(data, 0, bCount);
}
try
{
zipOut.closeEntry();
}
catch (IOException ioException)
{
logger.error("IOException when closing zip file entry",ioException);
}
}
catch (IllegalArgumentException iException)
{
logger.error("IllegalArgumentException while creating zip file",iException);
}
catch (java.util.zip.ZipException e)
{
//Duplicate entry: ignore and continue.
try
{
zipOut.closeEntry();
}
catch (IOException ioException)
{
logger.error("IOException when closing zip file entry",ioException);
}
}
finally
{
if (bContent != null)
{
try
{
bContent.close();
}
catch (IOException ioException)
{
logger.error("IOException when closing zip file",ioException);
}
}
}
}
catch (PermissionException e)
{
//Ignore
}
}
}
在此先感謝。
您可以使用信號量來限制併發用戶的數量。 – shmosel
不允許同時發生這麼多的併發zip進程。使用執行程序執行ziptask,並且可以調整用於它們的線程數量。 – Kayaman
考慮到您同時控制了讀取和寫入過程,'ZipOutputStream'與您的問題沒有關係,您可以改爲放置'OutputStream',任務不會改變。基本上你的問題類似於[這一個](http://stackoverflow.com/questions/667508/whats-a-good-rate-limiting-algorithm)。 – user3707125