【问题标题】:Unable to write > 1200 files to Google App Engine Java with GCS in development server无法使用开发服务器中的 GCS 将 > 1200 个文件写入 Google App Engine Java
【发布时间】:2014-10-13 14:21:38
【问题描述】:

在 GAE 的生产环境中将文件写入谷歌云存储运行良好。 但是当我尝试将我的生产数据(6-7GB)导入开发服务器时,当我尝试写入超过 1200 个文件时,我总是遇到错误。前 1200 个文件工作正常,但后来我总是遇到异常。这种情况下我需要删除一些文件,然后才能成功将其他文件写入GCS。

我的测试环境是:

  • appengine-gcs-client 0.4.2.
  • appengine-java-sdk-1.9.13
  • Win 7 Prof (x64)、NTFS、Eclipse Kepler

这是我使用的代码:

byte[] content = ..
GcsFilename fn = new GcsFilename("cms-gi-pdf", "zip-dwdwos--Nwrg1aTk7DSRn9gAWnT");
GcsFileOptions options = new GcsFileOptions.Builder().mimeType("binary/octet-stream").acl("project-private").build();
GcsOutputChannel outputChannel = gcsService.createOrReplace(fn, options);
outputChannel.write(ByteBuffer.wrap(content));
outputChannel.close();

异常发生在最后一行 (close())。这是堆栈跟踪:

15:43:40 警告 com.google.appengine.api.files.dev.FileMetadata:setFinalized:Caught 尝试写入 blob 时出现 IOException 15:43:40 INFO com.google.appengine.tools.cloudstorage.RetryHelper:doRetry:RetryHelper(11,88 毫秒,1 次尝试, com.google.appengine.tools.cloudstorage.GcsOutputChannelImpl$1@6abbeea): 尝试 #1 失败 [java.io.IOException],休眠 281 毫秒

...

com.google.appengine.tools.cloudstorage.RetriesExhaustedException: RetryHelper(8,866 秒,6 次尝试, com.google.appengine.tools.cloudstorage.GcsOutputChannelImpl$1@6abbeea): 失败太多,放弃 com.google.appengine.tools.cloudstorage.RetryHelper.doRetry(RetryHelper.java:127) 在 com.google.appengine.tools.cloudstorage.RetryHelper.runWithRetries(RetryHelper.java:166) 在 com.google.appengine.tools.cloudstorage.RetryHelper.runWithRetries(RetryHelper.java:156) 在 com.google.appengine.tools.cloudstorage.GcsOutputChannelImpl.close(GcsOutputChannelImpl.java:198) 在 de.daysout.generic.filesystem.gcs.GoogleCloudStorage.write(GoogleCloudStorage.java:45)

...

原因:com.google.appengine.api.files.FinalizationException 在 com.google.appengine.api.files.FileServiceImpl.translateException(FileServiceImpl.java:617) 在 com.google.appengine.api.files.FileServiceImpl.makeSyncCall(FileServiceImpl.java:594) 在 com.google.appengine.api.files.FileServiceImpl.open(FileServiceImpl.java:527) 在 com.google.appengine.api.files.FileServiceImpl.openForAppend(FileServiceImpl.java:471) 在 com.google.appengine.api.files.FileServiceImpl.openForAppend(FileServiceImpl.java:190) 在 com.google.appengine.api.files.FileServiceImpl.openWriteChannel(FileServiceImpl.java:171) 在 com.google.appengine.tools.cloudstorage.dev.LocalRawGcsService.append(LocalRawGcsService.java:181) 在 com.google.appengine.tools.cloudstorage.dev.LocalRawGcsService.finishObjectCreation(LocalRawGcsService.java:245) 在 com.google.appengine.tools.cloudstorage.GcsOutputChannelImpl$1.call(GcsOutputChannelImpl.java:201) 在 com.google.appengine.tools.cloudstorage.GcsOutputChannelImpl$1.call(GcsOutputChannelImpl.java:198) 在 com.google.appengine.tools.cloudstorage.RetryHelper.doRetry(RetryHelper.java:108)

... 72 更多原因:

com.google.apphosting.api.ApiProxy$ApplicationException: 应用程序错误:101: /gs/writable:oOUcuZuodalavuikpIHUFA?name=cms-gi-pdf%2Fzip-dwdwos--Nwrg1aTk7DSRn9gAWnT 已经在 com.google.appengine.api.files.dev.LocalFileService.throwError(LocalFileService.java:201) 在 com.google.appengine.api.files.dev.LocalFileService.open(LocalFileService.java:299) ...

这是可重现的。直到昨天我还在使用 appengine-gcs-client 0.2。但我对那个版本有同样的问题。这很烦人,因为我无法使用生产数据测试我的软件。

这是我的问题:

  • 这是一个错误还是开发服务器有任何限制?
  • 有没有人在开发服务器中使用过 appengine-gcs-client 的文件超过 1200 个?

【问题讨论】:

    标签: java google-app-engine development-environment google-cloud-storage


    【解决方案1】:

    这听起来像是开发服务器上“GCS”的自然限制。如您所见,.close() 期间的错误来自尝试完成写入。由于无法写入超过限制,finalize writes 代码正在发生 IOExceptions,因此正在尝试重试写入。天真地,它不知道为什么会发生 IOException,并且只是重试,就好像磁盘出现故障或忙碌一样。请问您是否在启动 devserver 时指定了存储位置,或者您的磁盘是否已满?

    这实际上归结为 devserver 不是生产服务器。你可以做很多事情,但在数千个对象中处理 7GB 的“GCS”显然不是其中之一。如果您打算在本地运行它们,我建议编写不需要使用那么多数据的测试。您应该在精心挑选的小型案例上进行测试,并相信平台能够在您实际推送更多对象时大规模执行。您也可以随时编写完整性测试以在您的生产数据上运行。

    【讨论】:

    • 感谢您的回答。我使用 732GB 几乎为空的 NTFS 分区。我在启动 devserver (-war D:\myproject) 时使用默认的 eclipse 设置。目前我只在 devserver 上使用我的数据库的一个子集。不幸的是,这意味着我无法测试一些日常运行的管理作业(仅适用于完整的数据集)。所以我只能在生产系统上出现一些问题时才能确定它们。
    • 尽管磁盘有剩余空间,但 devserver 的后备“GCS”存储完全有可能无法处理如此大的大小。你能尝试使用最新的SDK吗? (1.9.17) 最后,我建议如果你有一段复杂的代码不能分解成更小的可单元测试函数,那么你实现一个使用整个函数的完整性检查测试,并在如果您真的想确保它正常工作,请定期进行生产。每周运行一次或在重大更改后运行一次,不应该打破任何配额。
    • 另外,Java 的 GCS 客户端现在是 0.6 版,所以也许从 0.2 升级会有帮助。
    猜你喜欢
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    • 1970-01-01
    • 1970-01-01
    • 2018-06-09
    • 2016-12-18
    相关资源
    最近更新 更多