【发布时间】:2013-02-13 17:47:48
【问题描述】:
我创建了一个 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 访问的公共后端,但我认为 google 不允许将系统服务(如 _ah/upload)作为后端运行。现在我的下一个方法是让 ah_upload 在触发后端处理后立即返回,然后在处理完成后调用另一个服务以获得我想要的原始响应。
【问题讨论】:
-
您是否从前端实例的后端获取?如果是这样,那么我猜是前端超时,而不是后端。如果是这种情况,请尝试公开后端并直接访问处理程序(正如您根据引用中的 URL 所做的那样)。
-
Paul,该请求来自我也在运行的公共后端。我最初有来自前端的请求,但怀疑这是问题所在,所以我将其移至后端。我不再收到硬性截止日期异常,但仍然收到这些超时。
-
那我不知道,我在python方面工作,所以我恐怕无法进一步发展。只要您没有触发请求,然后通过任何级别的前端实例等待响应(即,您应该只是通过一个处理程序检查更新,该处理程序只立即返回状态而不管后端作业状态如何)然后我'我不知所措。
-
好吧,也许这就是问题所在。我在前端上传器进程上有一个 GWT 客户端,它正在等待这一切完成。我认为这是一个异步 GWT 上传服务。我会仔细研究它并很快添加更多细节。
-
那就这样吧。当您的后端作业完成时将一个值放入 memcache 并使用前端检查该值(或数据存储以提高安全性),当然不要直接在任何类型的处理程序中等待任何级别的任何后端进程,只需触发然后他们返回或检查状态更新并返回。