URL抓取到我的域应用程序始终启动新实例。怎么避免这个?

时间:2012-06-07 17:59:52

标签: google-app-engine task urlfetch

我有一个延迟的任务来格式化HTML中的正文电子邮件,将UrlFetch写入我自己的应用程序域:

//Format body email in HTML
final Charset UTF8_CHARSET = Charset.forName("UTF-8");
final String FORMAT_EMAIL = "http://www." + NamespaceManager.getGoogleAppsNamespace() + "/email/formatEmail";

URL url = new URL(FORMAT_EMAIL);
HTTPRequest req = new HTTPRequest(url, HTTPMethod.POST, FetchOptions.Builder.withDeadline(60.0));
req.setPayload(Utils.getPostData(map, "UTF-8").getBytes());
HTTPResponse resp = urlFetchService.fetch(req);
if (resp.getResponseCode() == HttpURLConnection.HTTP_OK)
    bodyMessage = new String(resp.getContent(), UTF8_CHARSET);
//here create new task to send email
SendEmail sendEmail = new SendEmail(emailTO, nameTO, emailREPLYTO, nameREPLYTO, subject, bodyMessage);
queue.add(TaskOptions.Builder.withPayload(sendEmail));

我将一些params传递给servlet formatEmail来制作一个可爱的HTML电子邮件.. :) 此代码工作正常,创建新的推送任务,并成功发送电子邮件。

问题是这个任务总是在100%的时间内创建一个新实例,即使没有任何用户访问权限,也可以在代码结束时执行艰巨的任务并关闭实例。

如何避免这种情况?

如果我将UrlFetch设置为外部域而不是我自己的域,通常GAE不会为此创建新实例....不奇怪吗?

1 个答案:

答案 0 :(得分:1)

Java运行时不是多线程的,因此每个实例一次只能处理一个请求。当您的应用程序向自己发出请求时,通常没有可用于为新请求提供服务的免费实例 - 调用者已占用该空间。

您可以使用预热请求和空闲实例设置来确保有额外的实例来处理您的格式化请求,但似乎您可以直接在原始请求中调用格式化代码,而不是将HTTP请求发送到自己。

更新:尼克指出,这只是真的by default。您是否设置了<threadsafe>true</threadsafe>