1

我正在 appengine 中开发一个应用程序,我们希望能够使内容可供离线用户使用。这意味着我们需要获取所有使用过的 blobstore 文件并将它们保存以供离线用户使用。我正在使用服务器端来执行此操作,因此它只执行一次,而不是针对每个最终用户。我正在使用任务队列来运行这个过程,因为它很容易超时。假设所有这些代码都作为任务运行。

小型集合可以正常工作,但较大的集合会导致 appengine 错误 202,并且它会一次又一次地重新启动任务。以下是结合将 Zip 文件写入 GAE Blobstore并遵循Google Appengine JAVA中有关大型 zip 文件的建议的示例代码 -通过根据需要重新打开频道来压缩保存在 Blobstore 中的大量图像。还引用了AppEngine 错误代码 202 - 任务队列作为错误。

//Set up the zip file that will be saved to the blobstore
AppEngineFile assetFile = fileService.createNewBlobFile("application/zip", assetsZipName);
FileWriteChannel writeChannel = fileService.openWriteChannel(assetFile, true);
ZipOutputStream assetsZip = new ZipOutputStream(new BufferedOutputStream(Channels.newOutputStream(writeChannel)));

HashSet<String> blobsEntries = getAllBlobEntries(); //gets blobs that I need
saveBlobAssetsToZip(blobsEntries);

writeChannel.closeFinally(); 

......

private void saveBlobAssetsToZip(blobsEntries) throws IOException  {        
    for (String blobId : blobsEntries) {

        /*gets the blobstote key that will result in the blobstore entry - ignore the bsmd as 
        that is internal to our wrapper for blobstore.*/

        BlobKey blobKey = new BlobKey(bsmd.getBlobId());

        //gets the blob file as a byte array    
        byte[] blobData = blobstoreService.fetchData(blobKey, 0, BlobstoreService.MAX_BLOB_FETCH_SIZE-1);
        String extension = type of file saved from our metadata (ie .jpg, .png, .pfd)

        assetsZip.putNextEntry(new ZipEntry(blobId + "." + extension));

        assetsZip.write(blobData);
        assetsZip.closeEntry();
        assetsZip.flush();

        /*I have found that if I don't close the channel and reopen it, I can get a IO exception
        because the files in the blobstore are too large, thus the write a file and then close and reopen*/

        assetsZip.close();
        writeChannel.close();
        String assetsPath = assetFile.getFullPath();
        assetFile = new AppEngineFile(assetsPath);
        writeChannel = fileService.openWriteChannel(assetFile, true);
        assetsZip = new ZipOutputStream(new BufferedOutputStream(Channels.newOutputStream(writeChannel)));

    }
}

让它在 appengine 上运行的正确方法是什么?再次,小型项目工作正常并 zip 保存,但具有更多 blob 文件的大型项目会导致此错误。

4

1 回答 1

0

我敢打赌该实例内存不足。你在用appstats吗?它会消耗大量内存。如果这不起作用,您可能需要增加实例大小。

于 2014-11-12T00:34:16.473 回答