在异步网址抓取中阅读Google App Engine documentation:
该应用最多可同时拥有10个 异步URL提取调用
如果应用程序一次调用10次异步提取,会发生什么情况? Google App Engine是否会引发异常,或者只是将剩余呼叫排队等待为其提供服务?
答案 0 :(得分:9)
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报告的是一个不同的问题,与您的应用程序INTO最大同时连接有关。对于可计费的应用程序,这里没有实际限制,它只是扩展(根据1000毫秒规则)。
GAE无法知道您的请求处理程序将发出阻止URL提取,因此他看到的连接500与他的应用程序实际正在做的事情无关(如果您的平均请求响应时间是,则这是过于简单化的btw > 1000毫秒你可能会增加500倍。
答案 1 :(得分:6)
这是一个老问题,但我相信接受的答案是错误的或过时的,可能会让人感到困惑。我实际测试了几个月,但根据我的经验,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提出了一个URL Fetch Manager for Python,它将超出应用程序代码限制的异步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;
}
}
}
}
}
答案 2 :(得分:5)
500错误开始发生。静默。
只有在所有请求下查看日志时才会发现这些内容(不要列为错误)。它只是说“请求已中止,因为您达到了同时的请求限制”。
因此,当您进行大量异步调用时,请确保您可以处理其中一些调用。
答案 3 :(得分:1)