【问题标题】:SimpleHttpConnectionManager being used incorrectly w/ Objectify使用 Objectify 错误地使用 SimpleHttpConnectionManager
【发布时间】:2018-05-31 04:16:53
【问题描述】:

我正在尝试使用 Objectify 保存多个数据存储实体,并不断收到数十条“SimpleHttpConnectionManager 使用不正确”的警告。

我正在使用以下代码来保存实体(我尝试过使用和不使用 .now() 调用):

ofy().save().entities(entities).now();

此外,在大约前半打警告之后,我得到以下异常:

SEVERE: exception occurred while calling backend method
com.google.appengine.tools.remoteapi.RemoteApiException: remote API call: I/O error
Caused by: java.net.SocketTimeoutException: Read timed out

如果我遍历 entities 并单独保存每个实体,我不会收到任何警告,但由于多次调用数据存储的速度和成本,这并不理想。

我保存了大约 2500 个实体,并尝试将 entities 分解为多个列表(少于 1000 个项目),但收到相同的警告。

这是 Objectify 的问题还是我错过了一个步骤?我应该根本不使用 Objectify 吗?

【问题讨论】:

  • 听起来可能与 google-cloud-intellij 插件使用的本地开发服务器 (dev_appserver) 中的错误有关。

标签: java google-app-engine google-cloud-datastore google-cloud-endpoints objectify


【解决方案1】:

这与 Objectify 无关。 Objectify 是一层薄薄的代码,可将您的 POJO 映射到 Google API 使用的较低级别的类似 hashmap 的对象。在大多数情况下,Objectify 操作将一对一转换为低级 API 调用。

如果您重写应用以使用低级 API 执行相同的操作,您将看到完全相同的问题。带有 RemoteApiException 的堆栈跟踪来自 Google 的 DatastoreService.put() 方法的深处。

我想你是从开发服务器收到这个错误的(这将是非常奇怪的服务器端)。谷歌最近重写了应用引擎开发服务器,不幸的是,当出现问题时,它往往会产生这样的不透明错误。我会将此作为错误报告给 Google - 但请确保向他们提供完整的堆栈跟踪。在this page 上向下滚动到“创建新的 App Engine 问题”。

【讨论】:

    【解决方案2】:

    根据您提供的信息,您可以查看几项以解决您的 Datastore 问题,让我来看看所有这些:

    • ID 生成:您使用的是哪种 ID 分配策略?请记住,如果您使用自动生成的@IDs,则在使用异步保存(没有.now() 调用的调用)时必须pay special attention,因为它们不会自动填充ID 值实体实例。因此,在这种情况下,您最好使用同步保存(使用 .now() 调用)以避免可能出现的问题。您还可以使用自己的 ID 分配,以避免操作等待完成异步任务。
    • 本地开发:在对您的问题的评论中,您提到该问题可能与本地开发服务器有关,因此如果您确实在使用 dev_appserver 会很有趣,并且在这样的情况下案例,如果您也在使用local Datastore emulator。这就将我们带到了上一个主题,因为如果您使用本地 Datastore 模拟器并希望获得自动生成的 ID,则需要指定用于此类生成的策略。
    • Objectify:我本人对 Objectify 第三方库的工作并不多,但是您需要了解的重要一点是 it is not thread-safe,因此应该从单个线程中使用 Objectify 实例.然后,您需要确认您正在使用的 AppEngine 应用程序不是线程安全的,并且没有使用来自不同线程的相同 Objectify 实例,因为这可能会导致错误。请注意,Cloud Platform 不提供对 Objectify 库(作为第三方库)的支持,并且它的使用仅供参考,因此如果您一直遇到问题,我建议您使用其中一种替代方案对于connecting to Datastore from AppEngine,这会将我们带到最后一点。
    • Datastore API 和客户端库:这是 Google 支持的两个替代方案,可用于从 AppEngine 连接到 Datastore。 Datastore API 提供commit handler 来对实体进行操作。您可以使用它在同一调用中插入实体列表。最后,Java 的 Client Library 提供了 datastore.add() method 用于插入单个实体或成批的实体(尽管它仅适用于 Java 8)。

    所以让我总结一下,让一切变得清晰:首先,确认您是在本地运行应用程序还是在使用 AppEngine 的生产环境中运行应用程序(然后确认您是否使用 Datastore 模拟器);然后,检查您的 ID 生成策略和调用类型(同步或异步),以及它们如何适合您的环境;最后,如果您在使用 Objectify 时一直遇到问题,请考虑查看 Google 专门支持的其他替代方案。

    【讨论】:

      猜你喜欢
      • 2011-03-06
      • 2014-04-17
      • 2017-06-01
      • 2017-04-01
      • 2014-06-03
      • 2012-10-01
      • 1970-01-01
      • 2020-04-23
      • 1970-01-01
      相关资源
      最近更新 更多