SimpleHttpConnectionManager 被错误地使用 w/ Objectify
SimpleHttpConnectionManager being used incorrectly w/ Objectify
我正在尝试使用 Objectify 保存多个数据存储实体,但不断收到数十条 "SimpleHttpConnectionManager being used incorrectly" 警告。
我正在使用以下代码保存实体(我尝试过使用和不使用 .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 吗?
根据您提供的信息,您可以查看几项内容以解决您的 Datastore 问题,所以让我回顾一下所有内容:
- ID生成:您使用的是哪种ID分配策略?请记住,如果您正在使用 自动生成的 @IDs,则在使用异步保存(没有
.now()
调用的调用)时必须 pay special attention,因为它们不会自动填充实体实例上的 ID 值。因此,在这种情况下,您最好使用同步保存(使用 .now()
调用)以避免可能出现的问题。您还可以使用自己的 ID 分配,以避免操作等待完成异步任务。
- 本地开发:在您的问题的评论中,您提到该问题可能与本地开发服务器有关,因此了解您是否确实在使用会很有趣
dev_appserver
,在这种情况下,如果您也在使用 local Datastore emulator。这就把我们带到了上一个主题,因为如果您使用的是本地数据存储模拟器并希望获得自动生成的 ID,则需要指定用于此类生成的策略。
- Objectify:我本人并没有太多使用 Objectify 第三方库,但是您需要了解的重要一点是 it is not thread-safe, so an Objectify instance should be used from a single thread. Then, you need to confirm that the AppEngine application you are working with is not threadsafe and is not making use of the same Objectify instance from different threads, as that may cause errors. Note that Cloud Platform does not provide support for the Objectify library (being a third-party library), and its use is only held as reference, so if you keep having problems with it, I'd suggest you move to one of the alternatives for connecting to Datastore from AppEngine,它把我们带到最后一点。
- Datastore API 和 Client Library:这是两个 Google 支持的备选方案,可用于从 AppEngine 连接到 Datastore。 Datastore API 提供
commit
handler to operate over entities. You can use it to insert a list of entities on the same call. Finally, the Client Library for Java provides the datastore.add()
method 用于插入单个实体或批量实体(尽管它仅适用于 Java 8)。
所以让我总结一下,让一切都清楚:首先,确认您的应用程序是在本地 运行 还是使用 AppEngine 在生产环境中使用(然后确认您是否在使用 Datastore 模拟器);然后,检查您的 ID 生成策略和调用类型(同步或异步),以及它们如何适合您的环境;最后,如果您在使用 Objectify 时一直遇到问题,请考虑查看 Google.
特别支持的其他替代方案
这与 Objectify 无关。 Objectify 是一层薄薄的代码,可将您的 POJO 映射到 Google 的 API 使用的较低级别的类似哈希图的对象。在大多数情况下,Objectify 操作将 1 对 1 转换为低级别 API 调用。
如果您重写您的应用程序以使用低级别 API 执行相同的操作,您将看到这个完全相同的问题。 RemoteApiException 的堆栈跟踪来自 Google 的 DatastoreService.put()
方法的深处。
我假设您是从开发服务器收到此错误(这在服务器端会很奇怪)。 Google 最近重写了 App Engine 开发服务器,不幸的是,当出现问题时,它往往会产生像这样的不透明错误。我会将此作为错误报告给 Google - 但请确保向他们提供完整的堆栈跟踪。向下滚动到 this page 上的 "Create new App Engine issue"。
我正在尝试使用 Objectify 保存多个数据存储实体,但不断收到数十条 "SimpleHttpConnectionManager being used incorrectly" 警告。
我正在使用以下代码保存实体(我尝试过使用和不使用 .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 吗?
根据您提供的信息,您可以查看几项内容以解决您的 Datastore 问题,所以让我回顾一下所有内容:
- ID生成:您使用的是哪种ID分配策略?请记住,如果您正在使用 自动生成的 @IDs,则在使用异步保存(没有
.now()
调用的调用)时必须 pay special attention,因为它们不会自动填充实体实例上的 ID 值。因此,在这种情况下,您最好使用同步保存(使用.now()
调用)以避免可能出现的问题。您还可以使用自己的 ID 分配,以避免操作等待完成异步任务。 - 本地开发:在您的问题的评论中,您提到该问题可能与本地开发服务器有关,因此了解您是否确实在使用会很有趣
dev_appserver
,在这种情况下,如果您也在使用 local Datastore emulator。这就把我们带到了上一个主题,因为如果您使用的是本地数据存储模拟器并希望获得自动生成的 ID,则需要指定用于此类生成的策略。 - Objectify:我本人并没有太多使用 Objectify 第三方库,但是您需要了解的重要一点是 it is not thread-safe, so an Objectify instance should be used from a single thread. Then, you need to confirm that the AppEngine application you are working with is not threadsafe and is not making use of the same Objectify instance from different threads, as that may cause errors. Note that Cloud Platform does not provide support for the Objectify library (being a third-party library), and its use is only held as reference, so if you keep having problems with it, I'd suggest you move to one of the alternatives for connecting to Datastore from AppEngine,它把我们带到最后一点。
- Datastore API 和 Client Library:这是两个 Google 支持的备选方案,可用于从 AppEngine 连接到 Datastore。 Datastore API 提供
commit
handler to operate over entities. You can use it to insert a list of entities on the same call. Finally, the Client Library for Java provides thedatastore.add()
method 用于插入单个实体或批量实体(尽管它仅适用于 Java 8)。
所以让我总结一下,让一切都清楚:首先,确认您的应用程序是在本地 运行 还是使用 AppEngine 在生产环境中使用(然后确认您是否在使用 Datastore 模拟器);然后,检查您的 ID 生成策略和调用类型(同步或异步),以及它们如何适合您的环境;最后,如果您在使用 Objectify 时一直遇到问题,请考虑查看 Google.
特别支持的其他替代方案这与 Objectify 无关。 Objectify 是一层薄薄的代码,可将您的 POJO 映射到 Google 的 API 使用的较低级别的类似哈希图的对象。在大多数情况下,Objectify 操作将 1 对 1 转换为低级别 API 调用。
如果您重写您的应用程序以使用低级别 API 执行相同的操作,您将看到这个完全相同的问题。 RemoteApiException 的堆栈跟踪来自 Google 的 DatastoreService.put()
方法的深处。
我假设您是从开发服务器收到此错误(这在服务器端会很奇怪)。 Google 最近重写了 App Engine 开发服务器,不幸的是,当出现问题时,它往往会产生像这样的不透明错误。我会将此作为错误报告给 Google - 但请确保向他们提供完整的堆栈跟踪。向下滚动到 this page 上的 "Create new App Engine issue"。