1

我创建了一个 App Engine 后端来为长时间运行的进程提供 http 请求。当查询引用小尺寸的输入时,后端进程按预期工作,但当输入尺寸大时,后端进程会超时。查询参数是 App Engine BlobStore blob 的 url,它是后端进程的输入数据。我认为使用 App Engine 后端的全部目的是避免 App Engine 前端拥有的超时限制。如何避免超时?

我这样调用后端,将连接超时长度设置为无限:

HttpURLConnection connection = (HttpURLConnection)(new URL(url + "?" + query).openConnection()); connection.setRequestProperty("Accept-Charset", charset); connection.setRequestMethod("GET"); connection.setConnectTimeout(0); connection.connect(); InputStream in = connection.getInputStream(); int ch; while ((ch = in.read()) != -1) json = json + String.valueOf((char) ch); System.out.println("Response Message is: " + json); connection.disconnect();

回溯(为匿名而编辑)是:

Uncaught exception from servlet java.net.SocketTimeoutException: Timeout while fetching URL: http://my-backend.myapp.appspot.com/somemethod?someparameter=AMIfv97IBE43y1pFaLNSKO1hAH1U4cpB45dc756FzVAyifPner8_TCJbg1pPMwMulsGnObJTgiC2I6G6CdWpSrH8TrRBO9x8BG_No26AM9LmGSkcbQZiilhC_-KGLx17mrS6QOLsUm3JFY88h8TnFNer5N6-cl0iKA at com.google.appengine.api.urlfetch.URLFetchServiceImpl.convertApplicationException(URLFetchServiceImpl.java:142) at com.google.appengine.api.urlfetch.URLFetchServiceImpl.fetch(URLFetchServiceImpl.java:43) at com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.fetchResponse(URLFetchServiceStreamHandler.java:417) at com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.getInputStream(URLFetchServiceStreamHandler.java:296) at org.someorg.server.HUDXML3UploadService.doPost(SomeService.java:70) at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)

如您所见,我没有收到 DeadlineExceededException,所以我认为除了 Google 的限制之外的其他原因导致了超时,并且也使这个问题与关于该主题的类似 stackoverflow 帖子不同。

我谦虚地感谢您的任何见解。

2012 年 2 月 19 日更新:我想我知道发生了什么。我应该能够让客户端无限期地等待使用 GWT [或任何其他类型的客户端异步框架] 异步处理程序来完成任何客户端请求,所以我认为这不是问题。问题是文件上传正在调用 _ah/upload App Engine 系统端点,一旦 blob 存储在 Blobstore 中,该端点就会调用上传服务的 doPost 后端来处理 blob。客户端对 _ah/upload 的请求是超时的,因为后端没有及时返回。为了让这个超时问题消失,我试图让 _ah_upload 服务本身成为一个公共后端,可以通过http://backend_name.project_name.appspot.com/_ah/upload访问,但我不认为谷歌允许系统服务(如_ah/upload)作为后端运行。现在我的下一个方法是让 ah_upload 在触发后端处理后立即返回,然后在处理完成后调用另一个服务以获得我想要的原始响应。

4

1 回答 1

0

解决方案是将后端进程作为任务启动并将其添加到任务队列中,然后在等待处理后端任务之前向客户端返回响应(这可能需要很长时间)。如果我可以将 ah_upload 分配给后端,这也将解决问题,因为客户端异步处理程序可以永远等待后端完成,但我认为 Google 不允许将系统 Servlet 分配给后端。正如 Paul C 所提到的,客户端现在必须轮询持久的后端进程响应数据,因为任务无法像普通 servlet 那样响应。

于 2013-02-20T14:44:42.707 回答