2010-01-23 101 views
0

我在Google App Engine上构建了一些东西,它可以充当iPhone应用程序的后端。在应用程序中,有一些互动通过他们的API推送到社交网络。因此,典型的工作流程是这样的:Google App Engine - 你如何处理DatastoreTimeoutException?

  1. 用户使用iPhone应用程序做的“东西”
  2. App Engine应用程序是通过HTTP惊动
  3. App Engine的提醒,用户做了社交网络“的东西。”如果用户要在该网络上检查他们的个人资料,他们将通过应用程序显示他们的活动。所以,就用户而言,他们可能做了什么。
  4. App Engine需要自己做一些持久性,但是当它尝试时,会引发DatastoreTimeException。现在数据处于一种怪异的状态。

那么处理这个问题的好方法是什么?根据问题的性质,我很乐意将它包装在“交易”中,但无法回滚发送到社交网络的内容。所以,我正在思考如何处理DatastoreTimeException?我是否应该将它包装在试块中,并再次尝试?向用户显示一个错误是否是一个更好的主意,然后当他们再次尝试时,“跳过”社交网络交互以便它不会被推出两次?有没有另一个想法,我没有想到这里?

回答

0

http://code.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/DatastoreTimeoutException.html

“当你试图把,得到,或有太多的属性删除太多的实体或实体,或者如果数据存储超载或遇到问题就会发生这种情况。”

如果您经常看到异常,我期望这是因为数据存储操作太大,因此重试并不会真正起到帮助作用。如果你只是防御性地防范可能抛出异常的风险,那么你可以再试一次(也许通过排队这样做的任务,但是如果你不能打数据存储,谁能说你可以排队任务)

如果你想成为防弹强劲,可以保证操作你的社交网络上执行是幂等(可重复),则:

  • 记到自己,您需要执行社交网络操作。
  • 如果笔记未能存储,中止并返回失败。
  • 否则,尝试社交网络操作。
  • 如果成功,请删除注释。
  • 有一些任务或循环将来重试任何剩余的笔记。

当然你必须要有点小心你给回iPhone客户端的响应代码,因为成功可以采取时间 - 比iPhone应用程序的请求的持续时间长。所以你希望你的应用引擎请求也是幂等的,你可能想要某种取消。

如果你从社交网络获得的所有成功或失败,如果成功,操作不能重复,那么你有麻烦了。这是一种在网络上提供的垃圾API,因为仅仅因为Web服务器向您发送成功的响应并不意味着您已收到响应,所以即使成功创建责任,调用者有时也无法知道他们已经成功。但它发生。

+0

实际上,重试通常是成功的;即使对于小型操作,您也会定期获取数据存储超时。 – geoffspear 2010-01-23 14:59:34

+0

这就是我的意思 - 如果因为数据存储故障而失败,那么重试就很好。如果因为你的实体太大而失败,那么重试就会永远流失。假设这是一个小故障,这个持续时间大概决定了你是否可以在一个简单的循环中重试(在你的请求超时之前),或者你需要一个任务(因为解决“怪异状态” )。但是我在应用引擎上没有这方面的经验。 – 2010-01-23 15:10:49

+0

该对象有几个属性 - 一个字符串,一个长,几个日期和几个整数。这可能会被视为“太大”,或者可以肯定,这是一个小故障(这是我唯一看到它的时间)。 – bpapa 2010-01-24 02:29:34

0

我觉得这句话令人担忧: 实际上,重试通常是成功的;即使对于小型操作,您也会定期获取数据存储超时。 - Wooble 1月23日14:59

如果GAE有可靠性问题,怎么能认真对待GAE?通常你会发现数据存储缓慢?你对这些例外频率的估计是多少?

+0

这不是问题的答案 – bpapa 2010-01-26 18:34:33

0

这是任何分布式系统的基本问题。一般来说,没有简单的“防弹”解决方案。如果可能的话,最好的选择是确保你的一个或两个操作是幂等的 - 也就是说,多次执行它们都没有效果。对于数据存储来说,这很简单:如果指定了一个键名,多个put将会简单地相互覆盖。如果可能的话,你也应该在你的社交API中使用幂等性,以便在失败的情况下安全地重新执行。