13

通过 appstats,我可以看到我的数据存储查询大约需要 125 毫秒(api 和 cpu 结合),但在执行查询之前通常有很长的延迟(例如,高达 12000 毫秒)。

我可以看到我的数据存储延迟与我的查询无关(例如,相同的查询/数据有很大不同的延迟),所以我假设这是应用引擎的调度问题。

其他人是否看到同样的问题?

有没有办法减少延迟(例如管理控制台设置)?

这是来自 appstats 的屏幕截图。这个 servlet 几乎没有 cpu 处理。它执行 getObjectByID,然后执行数据存储查询。该查询有一个 OR 运算符,因此它被应用引擎转换为 3 个查询。

应用统计截图 . 如您所见,在第一个 getObjectByID 执行之前需要 6000 毫秒。get操作前没有任何处理(除了获取pm)。我认为这 6000 毫秒的延迟可能是由于实例预热,所以我将空闲实例增加到 2 以防止任何预热。

然后在 getObjectByID 和查询之间有大约 1000 毫秒的第二次延迟。获取和查询之间有零行代码。该代码仅获取 getObjectByID 的结果并将数据用作查询的一部分。

总计为 8097 毫秒,但我的数据存储操作(以及 99.99% 的 servlet)只有 514 毫秒(45 毫秒 api),尽管每次运行 servlet 时数字都会发生变化。这是另一个针对相同数据在同一 servlet 上运行的 appstats 屏幕截图。 在此处输入图像描述

这是我的java代码的基础知识。为了安全起见,我不得不删除一些细节。

user = pm.getObjectById(User.class, userKey);           
//build queryBuilder.append(...
final Query query = pm.newQuery(UserAccount.class,queryBuilder.toString());
query.setOrdering("rating descending");
query.executeWithArray(args); 

编辑:使用 Pingdom,我可以看到 GAE 延迟从 450 毫秒到 7,399 毫秒不等,或相差 1,644%!这是有两个空闲实例且站点上没有用户。 在此处输入图像描述

4

2 回答 2

9

我在一些应用程序中观察到非常相似的延迟(在 7000-10000 毫秒范围内)。我认为问题的大部分(那 6000 毫秒)不在于您的代码。

在我的观察中,这个问题与 AppEngine 启动一个新实例有关。设置最小空闲实例可能有助于缓解,但它不会解决它(我尝试了最多 2 个空闲实例),因为基本上即使你有 N 个空闲实例,应用引擎也会更喜欢启动动态实例,即使只有一个请求进来,并且会在出现疯狂的流量高峰时“保存”空闲的。这是非常违反直觉的,因为您希望它使用已经存在的实例并为将来的请求启动动态实例。

无论如何,根据我的经验,这个问题(10000ms 延迟)很少发生在任何非零负载量下,而且许多人不得不每隔几分钟恢复到某种 ping 之王(可能是 cron 作业)(以前工作 5 分钟)但最近实例死得更快,所以它更像是每 2 分钟一次 ping)以保持动态实例为在没有其他人打开时访问该站点的用户提供服务。这种 ping 并不理想,因为它会吃掉您的免费配额(每 5 分钟 ping 一次会吃掉一半以上),但到目前为止我真的还没有找到更好的选择。

回顾一下,总的来说,我发现应用程序引擎在负载下非常棒,但当您在网站上只有很少 (1-3) 个用户时,它并不出色。

于 2013-01-21T04:06:04.147 回答
1

Appstats 仅在您进行 GAE API/RPC 调用时帮助诊断性能问题。

对于您的图表,“空白”时间用于在您的实例上运行您的代码。这不会是安排时间。

您猜测初始延迟可能是因为实例预热很可能。它可能是正在执行的框架代码。我无法猜测 Get 和 Query 之间的延迟。可能是有 0 行代码,但是您在 Query 中调用了一些需要时间来处理的函数。

如果不了解语言、框架或实际代码,没有人可以帮助您。

您需要自行添加某种性能跟踪来诊断此问题。最简单(但不是非常准确)的方法是在代码执行时添加计时器并记录计时器值。

于 2013-01-19T17:39:20.587 回答