使用SpreadSheet API时无法完成HTTP请求

时间:2014-02-28 15:54:15

标签: java google-app-engine google-spreadsheet-api

我正在开发一个Google App Engine应用程序,它可以读取和编辑一个包含大约150列和500行的大型SpreadSheet。除了特定的大小(可能会有所不同),我正在寻找一种提高性能的方法,因为大多数时候我都会遇到500内部服务器错误(如下所示)。

  

java.lang.RuntimeException:无法完成HTTP请求   by:java.net.SocketTimeoutException:获取URL时超时:   https://spreadsheets.google.com/feeds/worksheets/xxxxxxxxxxxxxxxxxxxxxxx/private/full

在下面的代码片段中,您可以看到我如何阅读我的SpreadSheet以及哪一行引发异常。

for (SpreadsheetEntry entry : spreadsheets) {
    if (entry.getTitle().getPlainText().compareTo(spreadsheetname) == 0) {
        spreadsheet = entry;
    }
}

WorksheetFeed worksheetFeed = service.getFeed(spreadsheet.getWorksheetFeedUrl(), WorksheetFeed.class);
List<WorksheetEntry> worksheets = worksheetFeed.getEntries();
WorksheetEntry worksheet = worksheets.get(0);

URL listFeedUrl = worksheet.getListFeedUrl();
// The following line is the one who generates the error
ListFeed listFeed = service.getFeed(listFeedUrl, ListFeed.class);

for (ListEntry row : listFeed.getEntries()) {
    String content = row.getCustomElements().getValue("rowname");
    String content2 = row.getCustomElements().getValue("rowname2");
}

我已经使用结构化查询改进了性能。基本上我在URL中应用过滤器,这使我只能检索我需要的几行。请注意,无论如何,我仍然会收到上述错误。

URL listFeedUrl = new URI(worksheet.getListFeedUrl().toString() + "?sq=rowname=" + URLEncoder.encode("\"" + filter+ "\"").toString()).toURL();

然而,我的问题是不同的,首先在某些时候我必须读取所有行但只有少数列(大约5)。我仍然需要找到一种方法来实现这一点,我知道有另一个参数“tq”允许选择列,但该语句需要字母符号(如A,B,AA),我想使用而是列名。

最重要的是我需要摆脱500内部服务器错误。因为它听起来像一个超时问题,我想把这个值增加到合理的时间。我的用户也可以等几秒钟,因为它看起来完全随机。当它工作时,它在大约2-3秒内加载页面。当它不起作用但是我得到500内部服务器错误,这对最终用户来说真的很令人沮丧。

有什么想法吗?我在App Engine设置上找不到任何内容。到目前为止,我唯一的想法是将电子表格拆分为多个电子表格(或工作表),以便读取更少的列。但是,如果有一个选项可以让我增加超时,那就太棒了。

编辑:我在互联网上四处寻找,我可能找到了可以帮助我的东西。我刚发现服务对象提供了一个setConnectionTimeout方法,立即进行测试。

// Set timeout

int timeout = 60000;
service.setConnectTimeout(timeout);

2 个答案:

答案 0 :(得分:2)

真正的问题是你不应该使用电子表格。如果你试图大量使用,它会抛出许多错误,包括速率限制。 您至少需要使用指数退避来重试错误,但仍然会很慢。通过url进行查询也没有效率。 解决方案是将spresdsheet转储到数据存储区中,然后从那里执行查询。由于您还编辑了电子表格,因此与数据存储区数据保持同步并非易事。一般解决方案要求任务队列正确处理超时和大量数据(单元格)

答案 1 :(得分:2)

超时

我使用10秒的时间重试。它适用于我。

纸张尺寸

我一次使用80,000个细胞。它工作正常,我没有看到重试失败。我正在使用CellFeed,而不是ListFeed。

是的,它不喜欢大片,1000片左右的小片更快。即使我只写部分纸张,小纸张也要快得多。 (感觉它重新计算了整张纸,因为看起来并不算数据量,但我不确定)

指数退避

Zig建议指数退避 - 对数字感兴趣 - 人们通过指数退避获得的超时值和失败率 - 以及纸张尺寸的影响。

我怀疑从3秒时间开始,并且每次重试可能会有效,但尚未测试。