阅读有关异步 URL 获取的 Google App Engine文档:
该应用最多可以同时进行 10 个异步 URL Fetch 调用
如果应用程序一次调用超过 10 个异步获取会发生什么?
Google App Engine 是否会引发异常或只是将剩余的呼叫排队等待为它们服务?
阅读有关异步 URL 获取的 Google App Engine文档:
该应用最多可以同时进行 10 个异步 URL Fetch 调用
如果应用程序一次调用超过 10 个异步获取会发生什么?
Google App Engine 是否会引发异常或只是将剩余的呼叫排队等待为它们服务?
嗯,Swizzec 不正确。很容易测试:
rpc = []
for i in range(1,20):
rpc.append(urlfetch.createrpc())
urlfetch.make_fetch_call(rpc[-1],"http://stackoverflow.com/questions/3639855/what-happens-if-i-call-more-than-10-asynchronous-url-fetch")
for r in rpc:
response = r.get_result().status_code
这不会返回任何异常。事实上,这很好用!请注意,对于不计费的应用程序,您的结果可能会有所不同。
Swizec 报告的是一个不同的问题,与您的应用程序的最大同时连接数有关。顺便说一句,对于计费应用程序,这里没有实际限制,它只是向外扩展(受 1000 毫秒规则约束)。
GAE 无法知道您的请求处理程序将发出阻塞 URL 获取,因此他看到的连接 500 与他的应用程序实际执行的操作无关(顺便说一句,如果您的平均请求响应时间 > 1000 毫秒,您的增加 500 的可能性)。
这是一个老问题,但我认为接受的答案不正确或过时,可能会使人们感到困惑。我实际上已经测试了几个月,但根据我的经验,Swizec 是非常正确的,GAE 不会排队,而是会失败大多数异步 URL 获取,超过每个请求大约 10 个同时获取的限制。
有关限制的说明,请参阅https://developers.google.com/appengine/docs/python/urlfetch/#Python_Making_requests和https://groups.google.com/forum/#!topic/google-appengine/EoYTmnDvg8U。
David Underhill 提出了一个用于 Python 的 URL Fetch Manager,它将超出应用程序代码限制的异步 URL 获取排队。
我为 Java 实现了类似的东西,它同步阻塞(由于缺少回调函数或 ListenableFutures)附加请求:
/**
* A URLFetchService wrapper that ensures that only 10 simultaneous asynchronous fetch requests are scheduled. If the
* limit is reached, the fetchAsync operations will block until another request completes.
*/
public class BlockingURLFetchService implements URLFetchService {
private final static int MAX_SIMULTANEOUS_ASYNC_REQUESTS = 10;
private final URLFetchService urlFetchService = URLFetchServiceFactory.getURLFetchService();
private final Queue<Future<HTTPResponse>> activeFetches = new LinkedList<>();
@Override
public HTTPResponse fetch(URL url) throws IOException {
return urlFetchService.fetch(url);
}
@Override
public HTTPResponse fetch(HTTPRequest request) throws IOException {
return urlFetchService.fetch(request);
}
@Override
public Future<HTTPResponse> fetchAsync(URL url) {
block();
Future<HTTPResponse> future = urlFetchService.fetchAsync(url);
activeFetches.add(future);
return future;
}
@Override
public Future<HTTPResponse> fetchAsync(HTTPRequest request) {
block();
Future<HTTPResponse> future = urlFetchService.fetchAsync(request);
activeFetches.add(future);
return future;
}
private void block() {
while (activeFetches.size() >= MAX_SIMULTANEOUS_ASYNC_REQUESTS) {
// Max. simultaneous async requests reached; wait for one to complete
Iterator<Future<HTTPResponse>> it = activeFetches.iterator();
while (it.hasNext()) {
if (it.next().isDone()) {
it.remove();
break;
}
}
}
}
}
500 错误开始发生。默默。
您只有在查看所有请求下的日志时才会发现这些(不要被列为错误)。它只是说“请求被中止,因为您达到了同时请求限制”。
因此,当您进行大量异步调用时,请确保您可以处理其中的一些异常。
看看这是否回答了你的问题:
http://groups.google.com/group/google-appengine/browse_thread/thread/1286139a70ef83c5?fwc=1